package com.link.base.base.policy.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.link.base.basic.dao.mybatis.mapper.BasicCommonMapper;
import com.link.base.basic.model.ListOfValue;
import com.link.base.user.model.CoreUser;
import com.link.base.base.accnt.model.Account;
import com.link.base.base.accnt.model.AcctAddress;
import com.link.base.base.accnt.service.AccountService;
import com.link.base.base.accnt.service.AcctAddressService;
import com.link.base.base.mvg.model.Mvg;
import com.link.base.base.mvg.service.MvgService;
import com.link.base.base.order.model.SaleOrder;
import com.link.base.base.order.model.SaleOrderItem;
import com.link.base.base.orderpayset.model.OrderPaySet;
import com.link.base.base.orderpayset.service.OrderPaySetService;
import com.link.base.base.orgnization.model.Orgnization;
import com.link.base.base.policy.dao.mybatis.mapper.*;
import com.link.base.base.policy.model.*;
import com.link.base.base.policy.model.*;
import com.link.base.base.product.model.PriceListItem;
import com.link.base.base.product.model.Product;
import com.link.base.base.product.service.PriceListItemService;
import com.link.base.base.product.service.ProductService;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.service.ServiceException;
import com.link.core.basic.service.BasicServiceImpl;
import com.link.core.basic.service.KeyGenerateService;
import com.link.core.util.StringUtils;
import com.link.core.util.UserUtil;
import com.link.base.base.policy.dao.mybatis.mapper.*;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author HuangLJ
 * @date 2018/11/5 11:00 AM
 * @comments 销售政策对象
 */
@Service
public class PolicyServiceImpl extends BasicServiceImpl<Policy> implements PolicyService {


    @Resource
    private PolicyMapper policyMapper;

    @Resource
    private PcyScpAccMapper pcyScpAccMapper;

    @Resource
    private PcyScpOrgMapper pcyScpOrgMapper;

    @Resource
    private PcyRuleMapper pcyRuleMapper;

    @Resource
    private PcyScpRgnMapper pcyScpRgnMapper;

    @Resource
    private PcyCndMapper pcyCndMapper;

    @Resource
    private PcyResultMapper pcyResultMapper;

    @Resource
    private KeyGenerateService keyGenerateService;

    @Resource
    private PcyAttributeService pcyAttributeService;

    @Resource
    private PcyAttributeMapper pcyAttributeMapper;

    @Resource
    private OrderPaySetService orderPaySetService;

    @Resource
    private ProductService productService;

    @Resource
    private PriceListItemService priceListItemService;

    @Resource
    private MvgService mvgService;

    @Resource
    private AccountService accountService;

    @Resource
    private BasicCommonMapper basicCommonMapper;

    @Resource
    private AcctAddressService acctAddressService;

    /**
     * 存放当前订单所用到的政策id
     */
    private List<String> currentPolicyCndIdList = null;

    @Override
    public BasicMapper<Policy> getBasicMapper() {
        return policyMapper;
    }

    @Override
    public void imgIdUpdate(Policy entity) throws Exception {
        policyMapper.imgIdUpdate(entity);
    }

    @Override
    public Policy getPolicyById(Policy entity) throws Exception {
        if (entity.getId() == null) {
            throw new ServiceException("POLICY-001");
        }
        Policy policy = policyMapper.queryById(entity);
        if (policy == null) {
            return null;
        }
        Long pcyId = policy.getId();
        //客户范围
        PcyScpAcc pcyScpAcc = new PcyScpAcc();
        pcyScpAcc.setPcyId(pcyId);
        pcyScpAcc.setPageFlag(false);
        List<PcyScpAcc> scpAccList = pcyScpAccMapper.queryByExamplePage(pcyScpAcc);
        policy.setScpAccList(scpAccList);

        //组织范围
        PcyScpOrg pcyScpOrg = new PcyScpOrg();
        pcyScpOrg.setPcyId(pcyId);
        pcyScpOrg.setPageFlag(false);
        List<PcyScpOrg> scpOrgList = pcyScpOrgMapper.queryByExamplePage(pcyScpOrg);
        policy.setScpOrgList(scpOrgList);

        //地域范围
        PcyScpRgn pcyScpRgn = new PcyScpRgn();
        pcyScpRgn.setPcyId(pcyId);
        pcyScpRgn.setPageFlag(false);
        List<PcyScpRgn> scpRgnList = pcyScpRgnMapper.queryByExamplePage(pcyScpRgn);
        policy.setScpRgnList(scpRgnList);

        //政策规则

        PcyRule pcyRule = new PcyRule();
        pcyRule.setPcyId(pcyId);
        String childTime = entity.getQueryTimeChild();
        if (childTime != null) {
            pcyRule.setQueryTime(childTime);
        }
        pcyRule.setPageFlag(false);
        List<PcyRule> ruleList = pcyRuleMapper.queryByExamplePage(pcyRule);
        policy.setRuleList(ruleList);

        //客户属性
        PcyAttribute pcyAttribute = new PcyAttribute();
        pcyAttribute.setPcyId(pcyId);
        pcyAttribute.setPageFlag(false);
        List<PcyAttribute> pcyAttributeList = pcyAttributeService.queryAttrByPcyId(pcyAttribute);
        policy.setPcyAttributeList(pcyAttributeList);

        //政策可见组织
//      Mvg mvg = new Mvg();
//      mvg.setMvgParentId(entity.getId());
//      mvg.setMvgMapperName("pcyOrgMvgMapper");
//      mvgService.queryRightListPage();

        if (ruleList != null && ruleList.size() > 0) {
            String str = "";
            Map<Long, PcyRule> ruleMap = new HashMap<Long, PcyRule>(ruleList.size());
            for (int i = 0; i < ruleList.size(); i++) {
                PcyRule rule = ruleList.get(i);
                Long ruleId = rule.getId();
                if (i == ruleList.size() - 1) {
                    str += "'" + ruleId + "'";
                } else {
                    str += "'" + ruleId + "',";
                }
                ruleMap.put(ruleId, rule);

            }
            str = "(" + str + ")";
            //规则条件
            PcyCnd pcyCnd = new PcyCnd();
            pcyCnd.setAttr2(str);
            pcyCnd.setPageFlag(false);
            List<PcyCnd> cndList = pcyCndMapper.queryByExamplePage(pcyCnd);
            for (int i = 0; cndList != null && i < cndList.size(); i++) {
                PcyCnd cnd = cndList.get(i);
                PcyRule rule = ruleMap.get(cnd.getRuleId());
                if (rule != null) {
                    if (rule.getConditionList() == null) {
                        rule.setConditionList(new ArrayList<PcyCnd>());
                    }
                    rule.getConditionList().add(cnd);
                }
            }

            //规则结果
            PcyResult pcyResult = new PcyResult();
            pcyResult.setAttr2(str);
            pcyResult.setPageFlag(false);
            List<PcyResult> resultList = pcyResultMapper.queryByExamplePage(pcyResult);
            for (int i = 0; resultList != null && i < resultList.size(); i++) {
                PcyResult result = resultList.get(i);
                PcyRule rule = ruleMap.get(result.getRuleId());
                if (rule != null) {
                    if (rule.getResultList() == null) {
                        rule.setResultList(new ArrayList<PcyResult>());
                    }
                    rule.getResultList().add(result);
                }
            }
        }
        return policy;
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void insertPolicy(Policy entity) throws Exception {

        Long pcyId = entity.getId();
        if (pcyId == null) {
            pcyId = keyGenerateService.keyGenerate();
            entity.setId(pcyId);
        }
        /*设置账套信息*/
        CoreUser currentUser = UserUtil.getUser();
        Long pcyCorpId = currentUser.getCorpid();
        if (null == pcyCorpId) {
            throw new ServiceException("PUBLIC-044");
        } else {
            entity.setCorpid(pcyCorpId);
        }
        //设置顺序
        Double seq = policyMapper.queryMaxSeq(entity);
        /*
        * 将顺序字段的空指针处理放在SQL中
        * */
//        seq = seq == null ? 1d : seq;
        String yFlag = "Y";
        String nFlag = "N";
        if (yFlag.equals(entity.getIsTop())) {
            //置顶
            entity.setRcmdSeq(seq + 1);
        } else if (nFlag.equals(entity.getIsTop())) {
            //随机
            entity.setRcmdSeq(seq - 1);
        }
        policyMapper.insert(entity);
        policyMapper.imgIdUpdate(entity);
        //政策规则
        List<PcyRule> ruleList = entity.getRuleList();
        if (ruleList != null) {
            for (PcyRule rule : ruleList) {
                Long ruleId = rule.getId();
                if (ruleId == null) {
                    ruleId = keyGenerateService.keyGenerate();
                    rule.setId(ruleId);
                }
                rule.setPcyId(pcyId);
                pcyRuleMapper.insert(rule);

                //规则条件
                List<PcyCnd> conditionList = rule.getConditionList();
//              setConditionList(conditionList, rule);//先调用函数处理坎级的上区间
                for (int j = 0; conditionList != null && j < conditionList.size(); j++) {
                    PcyCnd cnd = conditionList.get(j);
                    Long cndId = cnd.getId();
                    if (cndId == null) {
                        cndId = keyGenerateService.keyGenerate();
                        cnd.setId(cndId);
                    }
                    cnd.setRuleId(ruleId);
                    pcyCndMapper.insert(cnd);
                }
                //规则结果
                List<PcyResult> resultList = rule.getResultList();
                for (int j = 0; resultList != null && j < resultList.size(); j++) {
                    PcyResult result = resultList.get(j);
                    Long resultId = result.getId();
                    if (resultId == null) {
                        resultId = keyGenerateService.keyGenerate();
                        result.setId(resultId);
                    }
                    result.setRuleId(ruleId);
                    pcyResultMapper.insert(result);
                }
            }
        }
        //客户范围
        List<PcyScpAcc> scpAccList = entity.getScpAccList();
        for (int i = 0; scpAccList != null && i < scpAccList.size(); i++) {
            PcyScpAcc scpAcc = scpAccList.get(i);
            Long scpAccId = scpAcc.getId();
            if (scpAccId == null) {
                scpAccId = keyGenerateService.keyGenerate();
                scpAcc.setId(scpAccId);
            }
            scpAcc.setPcyId(pcyId);
            pcyScpAccMapper.insert(scpAcc);
        }

        //地域范围
        List<PcyScpRgn> scpRgnList = entity.getScpRgnList();
        for (int i = 0; scpRgnList != null && i < scpRgnList.size(); i++) {
            PcyScpRgn scpRgn = scpRgnList.get(i);
            Long scpRgnId = scpRgn.getId();
            if (scpRgnId == null) {
                scpRgnId = keyGenerateService.keyGenerate();
                scpRgn.setId(scpRgnId);
            }
            scpRgn.setPcyId(pcyId);
            pcyScpRgnMapper.insert(scpRgn);
        }

        //组织范围
        List<PcyScpOrg> scpOrgList = entity.getScpOrgList();
        for (int i = 0; scpOrgList != null && i < scpOrgList.size(); i++) {
            PcyScpOrg scpOrg = scpOrgList.get(i);
            Long scpOrgId = scpOrg.getId();
            if (scpOrgId == null) {
                scpOrgId = keyGenerateService.keyGenerate();
                scpOrg.setId(scpOrgId);
            }
            scpOrg.setPcyId(pcyId);
            pcyScpOrgMapper.insert(scpOrg);
        }

        //客户属性
        List<PcyAttribute> pcyAttributeList = entity.getPcyAttributeList();
        for (int i = 0; pcyAttributeList != null && i < pcyAttributeList.size(); ++i) {
            PcyAttribute pcyAttribute = pcyAttributeList.get(i);
            Long attrId = pcyAttribute.getId();
            if (attrId == null) {
                attrId = keyGenerateService.keyGenerate();
                pcyAttribute.setId(attrId);
            }
            pcyAttribute.setPcyId(pcyId);
            pcyAttributeMapper.insert(pcyAttribute);
        }

        //设置政策本身的可见组织
        List<Orgnization> orgnizationList = entity.getOrgnizationList();
        if (orgnizationList != null) {
            setPolicyOrg(orgnizationList, entity);
        }
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void updatePolicy(Policy entity) throws Exception {
        Long pcyId = entity.getId();
        /*设置账套信息*/
        Long pcyCorpId = entity.getCorpid();
        if (pcyId == null) {
            throw new ServiceException("POLICY-001");
        }
        //查询旧的政策数据
        Policy policy = new Policy();
        policy.setId(pcyId);
        policy.setCorpid(pcyCorpId);
        Double currentMaxSeq = policyMapper.queryMaxSeq(policy);
        /*
         * 将顺序字段的空指针处理放在SQL中
         * */
//        currentMaxSeq = currentMaxSeq == null ? 1d : currentMaxSeq;
        policy = this.getPolicyById(policy);

        if (policy == null) {
            throw new ServiceException("POLICY-002");
        }
        String flag = "Y";
        if (flag.equals(entity.getIsTop())) {
            //置顶
            if (currentMaxSeq.equals(entity.getRcmdSeq())) {
                entity.setRcmdSeq(currentMaxSeq + 1);
            }
        }
        //更新政策头
        policyMapper.update(entity);
        policyMapper.imgIdUpdate(entity);
        /*客户范围*/
        List<PcyScpAcc> scpAccList = entity.getScpAccList();
        List<PcyScpAcc> oldScpAccList = policy.getScpAccList();
        for (int i = 0; scpAccList != null && i < scpAccList.size(); i++) {
            PcyScpAcc scpAcc = scpAccList.get(i);
            Long scpAccId = scpAcc.getId();
            //新建数据
            if ("NEW".equals(scpAcc.getRow_status())) {
                if (scpAccId == null) {
                    scpAccId = keyGenerateService.keyGenerate();
                    scpAcc.setId(scpAccId);
                }
                scpAcc.setPcyId(pcyId);
                pcyScpAccMapper.insert(scpAcc);
            } else if ("UPDATE".equals(scpAcc.getRow_status())) {
                //更新数据
                if (scpAccId == null) {
                    throw new ServiceException("POLICY-003");
                }
                scpAcc.setPcyId(pcyId);
                pcyScpAccMapper.update(scpAcc);
            }
        }
        //找出无用数据并删除
        for (int i = 0; oldScpAccList != null && i < oldScpAccList.size(); i++) {
            PcyScpAcc oldScpAcc = oldScpAccList.get(i);
            boolean delFlag = true;
            for (int j = 0; oldScpAcc != null && scpAccList != null && j < scpAccList.size(); j++) {
                if (oldScpAcc.getId().equals(scpAccList.get(j).getId())) {
                    delFlag = false;
                    break;
                }
            }
            //删除客户范围数据
            if (delFlag) {
                pcyScpAccMapper.deleteById(oldScpAcc);
            }
        }

        /*更新客户属性*/
        List<PcyAttribute> pcyAttributeList = entity.getPcyAttributeList();
        List<PcyAttribute> oldPcyAttributeList = policy.getPcyAttributeList();
        setAccntAttr(pcyAttributeList, oldPcyAttributeList);


        /**地域范围*/
        List<PcyScpRgn> scpRgnList = entity.getScpRgnList();
        List<PcyScpRgn> oldScpRgnList = policy.getScpRgnList();
        for (int i = 0; scpRgnList != null && i < scpRgnList.size(); i++) {
            //更新插入数据
            PcyScpRgn scpRgn = scpRgnList.get(i);
            Long scpRgnId = scpRgn.getId();
            if ("NEW".equals(scpRgn.getRow_status())) {
                if (scpRgnId == null) {
                    scpRgnId = keyGenerateService.keyGenerate();
                    scpRgn.setId(scpRgnId);
                }
                scpRgn.setPcyId(pcyId);
                pcyScpRgnMapper.insert(scpRgn);
            } else if ("UPDATE".equals(scpRgn.getRow_status())) {
                if (scpRgnId == null) {
                    throw new ServiceException("POLICY-004");
                }
                scpRgn.setPcyId(pcyId);
                pcyScpRgnMapper.update(scpRgn);
            }
        }
        //删除多余地域范围信息
        for (int i = 0; oldScpRgnList != null && i < oldScpRgnList.size(); i++) {
            PcyScpRgn oldScpRgn = oldScpRgnList.get(i);
            boolean delFlag = true;
            for (int j = 0; scpRgnList != null && j < scpRgnList.size(); j++) {
                if (oldScpRgn.getId().equals(scpRgnList.get(j).getId())) {
                    delFlag = false;
                    break;
                }
            }
            if (delFlag) {
                pcyScpRgnMapper.deleteById(oldScpRgn);
            }
        }

        /*组织范围*/
        List<PcyScpOrg> scpOrgList = entity.getScpOrgList();
        List<PcyScpOrg> oldScpOrgList = policy.getScpOrgList();
        for (int i = 0; scpOrgList != null && i < scpOrgList.size(); i++) {
            //更新插入数据
            PcyScpOrg scpOrg = scpOrgList.get(i);
            Long scpOrgId = scpOrg.getId();
            if ("NEW".equals(scpOrg.getRow_status())) {
                if (scpOrgId == null) {
                    scpOrgId = keyGenerateService.keyGenerate();
                    scpOrg.setId(scpOrgId);
                }
                scpOrg.setPcyId(pcyId);
                pcyScpOrgMapper.insert(scpOrg);
            } else if ("UPDATE".equals(scpOrg.getRow_status())) {
                if (scpOrgId == null) {
                    throw new ServiceException("POLICY-005");
                }
                scpOrg.setPcyId(pcyId);
                pcyScpOrgMapper.update(scpOrg);
            }
        }
        //删除多余组织范围信息
        for (int i = 0; oldScpOrgList != null && i < oldScpOrgList.size(); i++) {
            PcyScpOrg oldScpOrg = oldScpOrgList.get(i);
            boolean delFlag = true;
            for (int j = 0; scpOrgList != null && j < scpOrgList.size(); j++) {
                if (oldScpOrg.getId().equals(scpOrgList.get(j).getId())) {
                    delFlag = false;
                    break;
                }
            }
            if (delFlag) {
                pcyScpOrgMapper.deleteById(oldScpOrg);
            }
        }

        /*政策规则 */
        List<PcyRule> ruleList = entity.getRuleList();
        List<PcyRule> oldRuleList = policy.getRuleList();
        //待更新条件
        List<PcyCnd> cndList = null;
        //待更新结果
        List<PcyResult> resultList = null;
        //原条件
        List<PcyCnd> oldCndList = null;
        //原结果
        List<PcyResult> oldResultList = null;
        for (int i = 0; ruleList != null && i < ruleList.size(); i++) {
            //更新插入数据
            PcyRule rule = ruleList.get(i);
            Long ruleId = rule.getId();
            if ("NEW".equals(rule.getRow_status())) {
                if (ruleId == null) {
                    ruleId = keyGenerateService.keyGenerate();
                    rule.setId(ruleId);
                }
                rule.setPcyId(pcyId);
                pcyRuleMapper.insert(rule);
            } else if ("UPDATE".equals(rule.getRow_status())) {
                if (ruleId == null) {
                    throw new ServiceException("POLICY-006");
                }
                rule.setPcyId(pcyId);
                pcyRuleMapper.update(rule);
            }
            //条件、结果统一添加到list
            if (rule.getConditionList() != null) {
                if (cndList == null) {
                    cndList = new ArrayList<PcyCnd>();
                }
                for (int j = 0; j < rule.getConditionList().size(); j++) {
                    rule.getConditionList().get(j).setRuleId(ruleId);
                    cndList.add(rule.getConditionList().get(j));
                }
            }

//          setConditionList(cndList, rule); //先调用函数处理坎级的上区间

            if (rule.getResultList() != null) {
                if (resultList == null) {
                    resultList = new ArrayList<PcyResult>();
                }
                for (int j = 0; j < rule.getResultList().size(); j++) {
                    rule.getResultList().get(j).setRuleId(ruleId);
                    resultList.add(rule.getResultList().get(j));
                }
            }
        }
        //删除多余规则信息
        for (int i = 0; oldRuleList != null && i < oldRuleList.size(); i++) {
            PcyRule oldRule = oldRuleList.get(i);
            boolean delFlag = true;
            for (int j = 0; ruleList != null && j < ruleList.size(); j++) {
                if (oldRule.getId().equals(ruleList.get(j).getId())) {
                    delFlag = false;

                    break;
                }
            }
            if (delFlag) {
                pcyRuleMapper.deleteById(oldRule);
            }
            //条件、结果统一添加到list
            if (oldRule.getConditionList() != null) {
                if (oldCndList == null) {
                    oldCndList = new ArrayList<PcyCnd>();
                }
                oldCndList.addAll(oldRule.getConditionList());
            }
            if (oldRule.getResultList() != null) {
                if (oldResultList == null) {
                    oldResultList = new ArrayList<PcyResult>();
                }
                oldResultList.addAll(oldRule.getResultList());
            }
        }

        /**
         * 条件
         */
        for (int i = 0; cndList != null && i < cndList.size(); i++) {
            PcyCnd cnd = cndList.get(i);
            Long cndId = cnd.getId();
            if ("NEW".equals(cnd.getRow_status())) {
                if (cndId == null) {
                    cndId = keyGenerateService.keyGenerate();
                }
                cnd.setId(cndId);
                pcyCndMapper.insert(cnd);
            } else if ("UPDATE".equals(cnd.getRow_status())) {
                if (cndId == null) {
                    throw new ServiceException("POLICY-007",cnd.getRuleId().toString());
                }
                pcyCndMapper.update(cnd);
            }
        }
        //删除无用条件
        for (int i = 0; oldCndList != null && i < oldCndList.size(); i++) {
            PcyCnd oldCnd = oldCndList.get(i);
            boolean delFlag = true;
            for (int j = 0; cndList != null && j < cndList.size(); j++) {
                if (cndList.get(j).getId() != null  && oldCnd.getId().equals(cndList.get(j).getId())) {
                    delFlag = false;
                    break;
                }
            }
            if (delFlag) {
                pcyCndMapper.deleteById(oldCnd);
            }
        }

        /**
         * 结果
         */
        for (int i = 0; resultList != null && i < resultList.size(); i++) {
            PcyResult result = resultList.get(i);
            Long resultId = result.getId();
            if ("NEW".equals(result.getRow_status())) {
                if (resultId == null) {
                    resultId = keyGenerateService.keyGenerate();
                }
                result.setId(resultId);
                pcyResultMapper.insert(result);
            } else if ("UPDATE".equals(result.getRow_status())) {
                if (resultId == null) {
                    throw new ServiceException("POLICY-008",result.getRuleId().toString());
                }
                pcyResultMapper.update(result);
            }
        }
        //删除无用结果
        for (int i = 0; oldResultList != null && i < oldResultList.size(); i++) {
            PcyResult oldResult = oldResultList.get(i);
            boolean delFlag = true;
            for (int j = 0; resultList != null && j < resultList.size(); j++) {
                if (resultList.get(j).getId() == null) {
                    continue;
                }
                if (oldResult.getId().equals(resultList.get(j).getId())) {
                    delFlag = false;
                    break;
                }
            }
            if (delFlag) {
                pcyResultMapper.deleteById(oldResult);
            }
        }

        //设置政策本身的可见组织
        List<Orgnization> orgnizationList = entity.getOrgnizationList();
        if (orgnizationList != null) {
            setPolicyOrg(orgnizationList, entity);
        }
    }

    /**
     * HuangLJ 更新组织MVG
     *
     * @param orgnizationList 组织列表
     * @throws Exception 抛错
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setPolicyOrg(List<Orgnization> orgnizationList, Policy policy) throws Exception {
        Long policyId = policy.getId();
        Mvg mvg = new Mvg();
        mvg.setPageFlag(false);
        mvg.setTotalFlag(true);
        mvg.setMvgMapperName("pcyOrgMvgMapper");
        mvg.setMvgParentId(policyId);
        mvgService.setMvgMapperName("pcyOrgMvgMapper");
        List<HashMap<String, String>> orgnizationMapOld = mvgService.queryRightListPage(mvg);
        String orgStr = JSON.toJSONString(orgnizationMapOld);
        List<Orgnization> orgnizationListOld = JSON.parseArray(orgStr, Orgnization.class);
        for (Orgnization item : orgnizationListOld) {
            boolean existFlag = false;
            for (Orgnization orgnization : orgnizationList) {
                if (item.getId().equals(orgnization.getId())) {
                    //如果相等，则设表示没有删除
                    existFlag = true;
                    break;
                }
            }
            if (!existFlag) {
                //如果不存在，则删除
                Mvg mvgDel = new Mvg();
                mvgDel.setMvgParentId(policyId);
                mvgDel.setMvgSubsetId(item.getId());
                mvgDel.setMvgMapperName("pcyOrgMvgMapper");
                mvgService.deleteById(mvgDel);
            }
        }

        //遍历，把新增的插入
        for (Orgnization orgnization : orgnizationList) {
            if ("NEW".equals(orgnization.getRow_status())) {
                //如果是新建，则把它插入
                Mvg mvgInsert = new Mvg();
                mvgInsert.setId(keyGenerateService.keyGenerate());
                mvgInsert.setMvgMapperName("pcyOrgMvgMapper");
                mvgInsert.setMvgParentId(policyId);
                mvgInsert.setMvgSubsetId(orgnization.getId());
                mvgService.insert(mvgInsert);
            }
        }
    }

    /**
     * HuangLJ 当规则类型为坎级的时候，设置上区间
     * 暂时不用
     *
     * @param conditionList 条件列表
     * @param pcyRule       规则对象，传递规则类型
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setConditionList(List<PcyCnd> conditionList, PcyRule pcyRule) throws Exception {
        String staircasePricing = "StaircasePricing";
        String ruleType = pcyRule.getRuleType();
        if (!staircasePricing.equals(ruleType)) {
            return;
        }
        //排序
        conditionList.sort((PcyCnd pcyCnd1, PcyCnd pcyCnd2) -> pcyCnd1.getCndMinimum().compareTo(pcyCnd2.getCndMinimum()));
        for (int i = 0; i < conditionList.size(); ++i) {
            if ((i + 1) == conditionList.size()) {
                //如果是最后一条数据，则设置为无穷大
                conditionList.get(i).setCndMaximum(900000000.0);
            } else {
                //否则，把下一条的最小值赋值到当前的最大值。
                conditionList.get(i).setCndMaximum(conditionList.get(i + 1).getCndMinimum());
            }
        }
    }


    /**
     * @param pcyAttributeList    属性列表
     * @param oldPcyAttributeList 老的属性列表
     * @throws Exception 报错
     *                   HuangLJ
     *                   更新客户属性
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setAccntAttr(List<PcyAttribute> pcyAttributeList, List<PcyAttribute> oldPcyAttributeList) throws Exception {
        for (int i = 0; pcyAttributeList != null && i < pcyAttributeList.size(); i++) {
            PcyAttribute pcyAttribute = pcyAttributeList.get(i);
            Long pcyId = pcyAttribute.getPcyId();
            Long pcyAttributeId = pcyAttribute.getId();
            //新建数据
            if ("NEW".equals(pcyAttribute.getRow_status())) {
                if (pcyAttributeId == null) {
                    pcyAttributeId = keyGenerateService.keyGenerate();
                    pcyAttribute.setId(pcyAttributeId);
                }

                pcyAttribute.setPcyId(pcyId);
                pcyAttributeMapper.insert(pcyAttribute);
            } else if ("UPDATE".equals(pcyAttribute.getRow_status())) {
                //更新数据
                if (pcyAttributeId == null) {
                    throw new ServiceException("POLICY-009");
                }
                pcyAttribute.setPcyId(pcyId);
                pcyAttributeMapper.update(pcyAttribute);
            }
        }
        //找出无用数据并删除
        for (int i = 0; pcyAttributeList != null && i < oldPcyAttributeList.size(); i++) {
            PcyAttribute oldPcyAttribute = oldPcyAttributeList.get(i);
            boolean delFlag = true;
            for (int j = 0; j < pcyAttributeList.size(); j++) {
                if (oldPcyAttribute.getId().equals(pcyAttributeList.get(j).getId())) {
                    delFlag = false;
                    break;
                }
            }
            //删除客户属性数据
            if (delFlag) {
                pcyAttributeMapper.deleteById(oldPcyAttribute);
            }
        }
    }

    /**
     * @param saleOrder 订单对象
     * @return 返回订单对象
     * @throws Exception 报错
     *                   HuangLJ
     *                   校验订单政策，返回应用了政策的订单信息
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    @Override
    public SaleOrder getPolicy(SaleOrder saleOrder) throws Exception {
        this.currentPolicyCndIdList = new ArrayList<String>();
        //订单一级类型
        String orderFirstType = saleOrder.getOrderType();
        //订单二级类型
        String orderChildType = saleOrder.getOrderChildType();
        //订单大类
        String orderKind = saleOrder.getOrderKind();
        if (StringUtils.isNull(orderFirstType)) {
            throw new ServiceException("POLICY-010");
        }

        if (StringUtils.isNull(orderChildType)) {
            throw new ServiceException("POLICY-011");
        }

        if (StringUtils.isNull(orderKind)) {
            throw new ServiceException("POLICY-012");
        }

        //获取订单参数,如果不需要校验政策，则直接返回本身
        OrderPaySet orderPaySetQuery = new OrderPaySet();
        orderPaySetQuery.setOrderFirstType(orderFirstType);
        orderPaySetQuery.setOrderSecondType(orderChildType);
        orderPaySetQuery.setOrderKind(orderKind);
        String flag = "Y";
        OrderPaySet orderPaySet = orderPaySetService.getByOrderType(orderPaySetQuery);
        if (orderPaySet == null || !flag.equals(orderPaySet.getCheckPolicyFlag())) {
            List<SaleOrderItem> saleOrderItemList = saleOrder.getSaleOrderItemList();
            for (SaleOrderItem saleOrderItem : saleOrderItemList) {
                String itemType = saleOrderItem.getItemType();
                if (!"Gift Item".equals(itemType)) {
                    //设置政策价为0
                    if (saleOrderItem.getPolicyPrice() == null) {
                        saleOrderItem.setPolicyPrice(0d);
                    }
                    saleOrderItem.setGenerateGiftFlag(false);
                }
            }
            //如果订单参数设置里面，没有设置校验逻辑或者校验逻辑不为Y ,则直接返回当前订单。不做政策获取
            return saleOrder;
        }

        //先清空当前政策信息，重新计算
        saleOrder.setProdDiscount(0d);
        saleOrder.setOrderDiscount(0d);
        saleOrder.setGeneratePolicyFlag(false);
        List<SaleOrderItem> saleOrderItemList = saleOrder.getSaleOrderItemList();

        //新用一个新的订单行列表，把老的赠品都存下来。
        List<SaleOrderItem> saleOrderItemListGift = new ArrayList<SaleOrderItem>();

        //删除当前订单行记录上的赠品，同时把非赠品的政策价格设置为0
        for (int i = 0; i < saleOrderItemList.size(); ++i) {
            String itemType = saleOrderItemList.get(i).getItemType();
            if (!"Gift Item".equals(itemType)) {
                //设置政策价为0
                saleOrderItemList.get(i).setPolicyPrice(0d);
                //设置是否已经生成赠品为false
                saleOrderItemList.get(i).setGenerateGiftFlag(false);
            } else {
                SaleOrderItem saleOrderItem = (SaleOrderItem) BeanUtils.cloneBean(saleOrderItemList.get(i));
                saleOrderItemListGift.add(saleOrderItem);
                saleOrderItemList.remove(i);
                --i;
            }
        }


        //获取所有当前满足当前客户的销售政策
        //下单客户id
        Long acctId = saleOrder.getAcctId();
        if (acctId == null) {
            throw new ServiceException("PUBLIC-026");
        }
        Policy policyQuery = new Policy();
        policyQuery.setTotalFlag(true);
        policyQuery.setPageFlag(false);
        policyQuery.setPcyStatus("Y");
        String ordDate = saleOrder.getOrderDate();
        if (ordDate == null) {
            ordDate = saleOrder.getCreated();
        }
        if (ordDate == null) {
            throw new ServiceException("POLICY-013");
        }
        SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = sDateFormat.parse(ordDate);

        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ordDate = f.format(date);
        policyQuery.setQueryTime(ordDate);
        List<Policy> policyListHead = this.queryByExamplePage(policyQuery);
        List<Policy> policyList = new ArrayList<Policy>();
        for (Policy policy : policyListHead) {
            policy.setQueryTimeChild(ordDate);
            Policy policyRet = getPolicyById(policy);
            if (policyRet != null) {
                policyList.add(policyRet);
            }
        }
        //剔除范围不合适的
        deleteOutRange(policyList, acctId);

        //计算政策
        setItemId(saleOrder);
        calculationPolicy(saleOrder, policyList);
        deleteItemId(saleOrder);
        //比较赠品信息，把多余的删除
        //List<SaleOrderItem> saleOrderItems = saleOrder.getSaleOrderItemList();
//      Double orderAmount = saleOrder.getOrderAmount();
//      Double disCount = 0d;
//          for (SaleOrderItem saleOrderItem : saleOrderItems) {
//              Double disCountPrice = saleOrderItem.getPolicyPrice();
//          Double manualPrice = saleOrderItem.getManualPrice();
//          Double promotionPrice =  saleOrderItem.getPromotionPrice();
//          if(!(manualPrice != null && manualPrice >0) && disCountPrice != null && disCountPrice>0){
//              Double num = saleOrderItem.getQty();
//              disCount = disCount +(promotionPrice - disCountPrice)*num;
//          }
//      }
        Double orderTotalAmount = saleOrder.getOrderTotalAmount();
        Double orderDiscount = saleOrder.getOrderDiscount();
        Double payAmount = orderTotalAmount + orderDiscount;
        for (SaleOrderItem saleOrderItem : saleOrder.getSaleOrderItemList()) {
            String itemType = saleOrderItem.getItemType();
            if (!"Gift Item".equals(itemType)) {
                Double sharePrice = saleOrderItem.getAmount();
//              if(saleOrderItem.getManualPrice()!=null && saleOrderItem.getManualPrice() >0) {
//                  sharePrice = saleOrderItem.getManualPrice();
//              }
//              else if(saleOrderItem.getPolicyPrice() != null && saleOrderItem.getPolicyPrice() >0) {
//                  sharePrice = saleOrderItem.getPolicyPrice();
//              }
//              else{
//                  sharePrice = 0.0;
//              }
                saleOrderItem.setWholeDiscountShare((sharePrice / payAmount) * orderDiscount);
            } else {
                saleOrderItem.setWholeDiscountShare(0.0);
            }
        }

        //设置订单行，如果政策价位0 ，则设置为空
        List<SaleOrderItem> saleOrderItemListEnd = saleOrder.getSaleOrderItemList();
        for (SaleOrderItem saleOrderItem : saleOrderItemListEnd) {
            Double policyPrice = saleOrderItem.getPolicyPrice();
            if (policyPrice != null && policyPrice == 0.0) {
                saleOrderItem.setPolicyPrice(null);
            }
        }

        return saleOrder;
    }

    /**
     * @param saleOrder
     * @throws Exception 报错
     * @auth HuangLJ
     * @Comments 给没有id的订单行添加id, 方便在设置政策对应关系的时候使用
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setItemId(SaleOrder saleOrder) throws Exception {
        Integer num = 0;
        for (SaleOrderItem saleOrderItem : saleOrder.getSaleOrderItemList()) {
            if (saleOrderItem.getId() == null) {
                ++num;
                saleOrderItem.setId(Long.parseLong("11111" + num));
            }
        }
    }

    /**
     * @param saleOrder
     * @throws Exception 报错
     * @auth HuangLJ
     * @Comments 给没有id的订单行添加id, 方便在设置政策对应关系的时候使用
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void deleteItemId(SaleOrder saleOrder) throws Exception {
        for (SaleOrderItem saleOrderItem : saleOrder.getSaleOrderItemList()) {
            Long id = saleOrderItem.getId();
            if ( id != null && id.toString().contains("11111")) {
                saleOrderItem.setId(null);
            }
        }
    }

    /**
     * @param policyList 政策列表
     * @param acctId     客户信息
     * @throws Exception 常规报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void deleteOutRange(List<Policy> policyList, Long acctId) throws Exception {
        Account accountQuery = new Account();
        accountQuery.setId(acctId);
        Account account = accountService.queryById(accountQuery);
        if (account == null) {
            throw new ServiceException("POLICY-014",acctId.toString());
        }
        for (int i = 0; policyList != null && i < policyList.size(); ++i) {
            Boolean orgFlag = checkOrg(account, policyList.get(i));
            Boolean addrFlag = checkAddr(account, policyList.get(i));
            Boolean accFlag = checkAcc(account, policyList.get(i));
            Boolean attrFlag = checkAttr(account, policyList.get(i));

            if (!(attrFlag && accFlag && addrFlag && orgFlag)) {
                policyList.remove(i);
                --i;
            }
        }
    }

    /**
     * @param account 客户信息
     * @param policy  政策信息
     * @return 是否已经存在
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private Boolean checkOrg(Account account, Policy policy) throws Exception {
        boolean existFlag = false;
        Long accntOrgId = account.getOrgId();
        if (accntOrgId == null) {
            return false;
        }
        List<PcyScpOrg> pcyScpOrgList = policy.getScpOrgList();
        if (pcyScpOrgList == null || pcyScpOrgList.size() < 1) {
            return true;
        }
        for (PcyScpOrg pcyScpOrg : pcyScpOrgList) {
            Long orgId = pcyScpOrg.getOrgId();
            if (accntOrgId.equals(orgId)) {
                existFlag = true;
                break;
            }
        }
        return existFlag;
    }

    /**
     * 校验客户地址是否满足
     *
     * @param account 客户对象
     * @param policy  政策对象
     * @return bool值
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private Boolean checkAddr(Account account, Policy policy) throws Exception {
        List<PcyScpRgn> pcyScpRgnList = policy.getScpRgnList();
        if (pcyScpRgnList == null || pcyScpRgnList.size() < 1) {
            return true;
        }

        boolean existFlag = false;
        //获取客户主要地址id
        Long addrId = account.getAcctAddressId();
        if (addrId == null) {
            return false;
        }
        //查询客户当前的地址信息
        AcctAddress acctAddressQuery = new AcctAddress();
        acctAddressQuery.setId(addrId);
        AcctAddress acctAddress = acctAddressService.queryById(acctAddressQuery);
        if (acctAddress == null) {
            return false;
        }
        String addrType = acctAddress.getAddrType();
        String receiveAddr = "RECEIVE_ADDR";
        if (!receiveAddr.equals(addrType)) {
            //如果当前地址不是收货地址，则略过
            return false;
        }
        String accnCity = acctAddress.getCity();
        String accnProvince = acctAddress.getProvince();
        if (StringUtils.isNull(accnCity) || StringUtils.isNull(accnProvince)) {
            return false;
        }

        for (PcyScpRgn pcyScpRgn : pcyScpRgnList) {
            //城市
            String city = pcyScpRgn.getAddrName();
            //省份
            String province = pcyScpRgn.getProvince();
            if (accnCity.equals(city) && accnProvince.equals(province)) {
                existFlag = true;
                break;
            }
        }
        return existFlag;
    }

    /**
     * 校验客户范围是否满足
     *
     * @param account 客户对象
     * @param policy  政策
     * @return bool值
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private Boolean checkAcc(Account account, Policy policy) throws Exception {
        boolean existFlag = false;
        Long id = account.getId();
        if (id == null) {
            return false;
        }
        List<PcyScpAcc> pcyScpAccList = policy.getScpAccList();
        if (pcyScpAccList == null || pcyScpAccList.size() < 1) {
            return true;
        }
        for (PcyScpAcc pcyScpAcc : pcyScpAccList) {
            Long accntId = pcyScpAcc.getAccntId();
            if (id.equals(accntId)) {
                existFlag = true;
                break;
            }
        }
        return existFlag;
    }

    /**
     * @param account 客户对象
     * @param policy  政策
     * @return bool值
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private Boolean checkAttr(Account account, Policy policy) throws Exception {
        boolean existFlag = false;
        String acctValue = account.getAcctType();
        String acctChildValue = account.getAcctChileType();

        List<PcyAttribute> pcyAttributeList = policy.getPcyAttributeList();
        if (pcyAttributeList == null || pcyAttributeList.size() < 1) {
            return true;
        }
        if (StringUtils.isNull(acctValue)) {
            return false;
        }
        for (PcyAttribute pcyAttribute : pcyAttributeList) {
            String attrCode = pcyAttribute.getAttrCode();
            String attrSubCode = pcyAttribute.getAttrSubCode();
            if (!StringUtils.isNull(acctChildValue)) {
                //如果客户子类型不为空，则校验子类型
                if (acctChildValue.equals(attrSubCode)) {
                    existFlag = true;
                    break;
                }
            } else if (acctValue.equals(attrCode)) {
                existFlag = true;
                break;
            }

        }
        return existFlag;
    }


    /**
     * HuanglJ 比较新的和老的赠品行差别。把该删除的删除掉。
     *
     * @param oldList 老的订单行（都是赠品）
     * @param genList 新生成的订单行（包括赠品）
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void compareGift(List<SaleOrderItem> oldList, List<SaleOrderItem> genList) throws Exception {
        for (SaleOrderItem saleOrderItem : genList) {
            if (!"Gift Item".equals(saleOrderItem.getItemType())) {
                continue; //如果不是赠品，则
            }

        }
    }

    /**
     * @param saleOrder 销售订单详细信息
     * @throws Exception 常规报错
     *                   HuangLJ
     *                   计算政策
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void calculationPolicy(SaleOrder saleOrder, List<Policy> policyList) throws Exception {
        //通过指定类型获取对应的政策列表
        //特价 满减 产品
        List<Policy> policyList1 = getPolicyByTypes(policyList, "Special Offer", "ConditionalPricing", "Product", "", "");
        //特价 坎级 产品
        List<Policy> policyList2 = getPolicyByTypes(policyList, "Special Offer", "StaircasePricing", "Product", "", "");
        policyList2.addAll(policyList1);
        sortPolicyListByRule(policyList2);
        if (policyList2.size() > 0) {
            calculationSaleOrderItem(policyList2, saleOrder);
        }


        //减价 满减 产品
        List<Policy> policyListReduction2 = getPolicyByTypes(policyList, "PriceReduction", "ConditionalPricing", "Product", "", "");
        //减价 坎级 产品
        List<Policy> policyList3 = getPolicyByTypes(policyList, "PriceReduction", "StaircasePricing", "Product", "", "");
        //折扣 满减 产品
        List<Policy> policyList4 = getPolicyByTypes(policyList, "PriceDiscount", "ConditionalPricing", "Product", "", "");
        //折扣 坎级 产品
        List<Policy> policyList5 = getPolicyByTypes(policyList, "PriceDiscount", "StaircasePricing", "Product", "", "");
        policyList5.addAll(policyListReduction2);
        policyList5.addAll(policyList3);
        policyList5.addAll(policyList4);
        sortPolicyListByRule(policyList5);
        if (policyList5.size() > 0) {
            calculationSaleOrderItem(policyList5, saleOrder);
        }


        //特价， 坎级，产品品牌， 单一产品
        List<Policy> policyList8 = getPolicyByTypes(policyList, "Special Offer", "StaircasePricing", "ProductBrand", "SingleProduct", "");
        //特价， 坎级，产品品牌， 产品组合
        List<Policy> policyList9 = getPolicyByTypes(policyList, "Special Offer", "StaircasePricing", "ProductBrand", "MixProduct", "");
        //特价， 坎级，产品系列，单一产品
        List<Policy> policyList12 = getPolicyByTypes(policyList, "Special Offer", "StaircasePricing", "ProductSeries", "SingleProduct", "");
        //特价， 坎级，产品系列，产品组合
        List<Policy> policyList13 = getPolicyByTypes(policyList, "Special Offer", "StaircasePricing", "ProductSeries", "MixProduct", "");
        policyList13.addAll(policyList8);
        policyList13.addAll(policyList9);
        policyList13.addAll(policyList12);
        sortPolicyListByRule(policyList13);
        if (policyList13.size() > 0) {
            calculationSaleOrderItem(policyList13, saleOrder);
        }


        //减价 满减 品牌 单品
        List<Policy> policyList14 = getPolicyByTypes(policyList, "PriceReduction", "ConditionalPricing", "ProductBrand", "SingleProduct", "");
        //减价 满减 品牌 全品牌
        List<Policy> policyList15 = getPolicyByTypes(policyList, "PriceReduction", "ConditionalPricing", "ProductBrand", "MixProduct", "");
        //减价 满减 系列（单品）全系列）
        List<Policy> policyList16 = getPolicyByTypes(policyList, "PriceReduction", "ConditionalPricing", "ProductSeries", "SingleProduct", "");
        //减价 满减 系列（单品）全系列）
        List<Policy> policyList17 = getPolicyByTypes(policyList, "PriceReduction", "ConditionalPricing", "ProductSeries", "MixProduct", "");
        //减价 坎级 品牌 单品
        List<Policy> policyList18 = getPolicyByTypes(policyList, "PriceReduction", "StaircasePricing", "ProductBrand", "SingleProduct", "");
        //减价 坎级 品牌 全品牌
        List<Policy> policyList19 = getPolicyByTypes(policyList, "PriceReduction", "StaircasePricing", "ProductBrand", "MixProduct", "");
        //减价 坎级 系列 单品
        List<Policy> policyList20 = getPolicyByTypes(policyList, "PriceReduction", "StaircasePricing", "ProductSeries", "SingleProduct", "");
        //减价 坎级 系列 全系列
        List<Policy> policyList21 = getPolicyByTypes(policyList, "PriceReduction", "StaircasePricing", "ProductSeries", "MixProduct", "");
        //折扣 满减 品牌 单品
        List<Policy> policyList22 = getPolicyByTypes(policyList, "PriceDiscount", "ConditionalPricing", "ProductBrand", "SingleProduct", "");
        //折扣 满减 品牌 产品组合
        List<Policy> policyList23 = getPolicyByTypes(policyList, "PriceDiscount", "ConditionalPricing", "ProductBrand", "MixProduct", "");
        //折扣 满减 系列 单品
        List<Policy> policyList24 = getPolicyByTypes(policyList, "PriceDiscount", "ConditionalPricing", "ProductBrand", "SingleProduct", "");
        //折扣 满减 系列 全品牌
        List<Policy> policyList25 = getPolicyByTypes(policyList, "PriceDiscount", "ConditionalPricing", "ProductBrand", "MixProduct", "");
        //折扣 坎级 品牌 单品
        List<Policy> policyList26 = getPolicyByTypes(policyList, "PriceDiscount", "StaircasePricing", "ProductBrand", "SingleProduct", "");
        //折扣 坎级 品牌 全品牌
        List<Policy> policyList27 = getPolicyByTypes(policyList, "PriceDiscount", "StaircasePricing", "ProductBrand", "MixProduct", "");
        //折扣 坎级 系列 单品
        List<Policy> policyList28 = getPolicyByTypes(policyList, "PriceDiscount", "Simple Ridge", "ProductSeries", "SingleProduct", "");
        //折扣 坎级 系列 全品牌
        List<Policy> policyList29 = getPolicyByTypes(policyList, "PriceDiscount", "StaircasePricing", "ProductSeries", "MixProduct", "");
        policyList29.addAll(policyList14);
        policyList29.addAll(policyList15);
        policyList29.addAll(policyList16);
        policyList29.addAll(policyList17);
        policyList29.addAll(policyList18);
        policyList29.addAll(policyList19);
        policyList29.addAll(policyList20);
        policyList29.addAll(policyList21);
        policyList29.addAll(policyList22);
        policyList29.addAll(policyList23);
        policyList29.addAll(policyList24);
        policyList29.addAll(policyList25);
        policyList29.addAll(policyList26);
        policyList29.addAll(policyList27);
        policyList29.addAll(policyList28);
        sortPolicyListByRule(policyList29);
        if (policyList29.size() > 0) {
            calculationSaleOrderItem(policyList29, saleOrder);
        }


        //设置订单行的赠送
        //赠送 满赠 产品
        List<Policy> policyList30 = getPolicyByTypes(policyList, "Buy Gifts", "ConditionalPricing", "Product", "", "Y");
        //赠送 坎级 产品
        List<Policy> policyList31 = getPolicyByTypes(policyList, "Buy Gifts", "StaircasePricing", "Product", "", "N");
        //赠送 循环坎级 产品
        List<Policy> policyList311 = getPolicyByTypes(policyList, "Buy Gifts", "StaircasePricing", "Product", "", "Y");
        policyList311.addAll(policyList30);
        policyList311.addAll(policyList31);
        sortPolicyListByRule(policyList311);
        if (policyList311.size() > 0) {
            calculationSaleOrderItem(policyList311, saleOrder);
        }


        //赠送 满赠 品牌 单品
        List<Policy> policyList32 = getPolicyByTypes(policyList, "Buy Gifts", "ConditionalPricing", "ProductBrand", "SingleProduct", "Y");
        //赠送 满赠 品牌 全品牌
        List<Policy> policyList33 = getPolicyByTypes(policyList, "Buy Gifts", "ConditionalPricing", "ProductBrand", "MixProduct", "Y");
        //赠送 满赠 系列 单品
        List<Policy> policyList34 = getPolicyByTypes(policyList, "Buy Gifts", "ConditionalPricing", "ProductSeries", "SingleProduct", "Y");
        //赠送 满赠 系列 全系列
        List<Policy> policyList35 = getPolicyByTypes(policyList, "Buy Gifts", "ConditionalPricing", "ProductSeries", "MixProduct", "Y");
        //赠送 坎级 品牌 单品
        List<Policy> policyList36 = getPolicyByTypes(policyList, "Buy Gifts", "StaircasePricing", "ProductBrand", "SingleProduct", "N");
        //赠送 坎级 品牌 全品牌
        List<Policy> policyList37 = getPolicyByTypes(policyList, "Buy Gifts", "StaircasePricing", "ProductBrand", "MixProduct", "N");
        //赠送 坎级 系列 单品
        List<Policy> policyList38 = getPolicyByTypes(policyList, "Buy Gifts", "StaircasePricing", "ProductSeries", "SingleProduct", "N");
        //赠送 坎级 系列 全系列
        List<Policy> policyList39 = getPolicyByTypes(policyList, "Buy Gifts", "StaircasePricing", "ProductSeries", "MixProduct", "N");
        //赠送 循环坎级 品牌 单品
        List<Policy> policyList40 = getPolicyByTypes(policyList, "Buy Gifts", "StaircasePricing", "ProductBrand", "SingleProduct", "Y");
        //赠送 循环坎级 品牌 全品牌
        List<Policy> policyList41 = getPolicyByTypes(policyList, "Buy Gifts", "StaircasePricing", "ProductBrand", "MixProduct", "Y");
        //赠送 循环坎级 系列 单品
        List<Policy> policyList42 = getPolicyByTypes(policyList, "Buy Gifts", "StaircasePricing", "ProductSeries", "SingleProduct", "Y");
        //赠送 循环坎级 系列 全系列
        List<Policy> policyList43 = getPolicyByTypes(policyList, "Buy Gifts", "StaircasePricing", "ProductSeries", "MixProduct", "Y");
        policyList43.addAll(policyList32);
        policyList43.addAll(policyList33);
        policyList43.addAll(policyList34);
        policyList43.addAll(policyList35);
        policyList43.addAll(policyList36);
        policyList43.addAll(policyList37);
        policyList43.addAll(policyList38);
        policyList43.addAll(policyList39);
        policyList43.addAll(policyList40);
        policyList43.addAll(policyList41);
        policyList43.addAll(policyList42);
        sortPolicyListByRule(policyList43);
        if (policyList43.size() > 0) {
            calculationSaleOrderItem(policyList43, saleOrder);
        }

        //设置订单头的满减，折扣

        //计算当前订单的价格
        //设置订单单品折扣价格
        setOrderPrice(saleOrder);

        //减价 满减 整单
        List<Policy> policyList44 = getPolicyByTypes(policyList, "PriceReduction", "ConditionalPricing", "Whole Order", "", "Y");
        //减价 坎级 整单
        List<Policy> policyList45 = getPolicyByTypes(policyList, "PriceReduction", "StaircasePricing", "Whole Order", "", "N");
        //折扣 满减 整单
        List<Policy> policyList46 = getPolicyByTypes(policyList, "PriceDiscount", "ConditionalPricing", "Whole Order", "", "N");
        //折扣 坎级 整单
        List<Policy> policyList47 = getPolicyByTypes(policyList, "PriceDiscount", "StaircasePricing", "Whole Order", "", "N");
        policyList47.addAll(policyList44);
        policyList47.addAll(policyList45);
        policyList47.addAll(policyList46);
        sortPolicyListByRule(policyList47);
        if (policyList47.size() > 0) {
            calculationSaleOrderHead(policyList47, saleOrder);
        }

        //设置订单头的赠送
        //赠送 满减 整单
        List<Policy> policyList48 = getPolicyByTypes(policyList, "Buy Gifts", "ConditionalPricing", "Whole Order", "", "Y");
        //赠送 坎级 整单
        List<Policy> policyList49 = getPolicyByTypes(policyList, "Buy Gifts", "StaircasePricing", "Whole Order", "", "N");
        policyList49.addAll(policyList48);
        sortPolicyListByRule(policyList49);
        if (policyList49.size() > 0) {
            calculationSaleOrderHead(policyList49, saleOrder);
        }

        //设置订单的应付金额
        Double orderPayAmount = saleOrder.getOrderTotalAmount();
        //整单折扣
        Double orderDiscount = saleOrder.getOrderDiscount();
        Double orderTotalAmount = orderPayAmount - orderDiscount;
        //设置整单应付金额
        saleOrder.setOrderTotalAmount(orderTotalAmount);

        //设置政策详细信息
        String policyMsg = getPolicyMsg(policyList, saleOrder, this.currentPolicyCndIdList);
        int len = 2000;
        if (policyMsg.length() > len) {
            policyMsg = policyMsg.substring(0, 2000);
        }
        saleOrder.setPolicyDetails(policyMsg);
    }


    /**
     * HuangLJ 设置订单的价格信息
     *
     * @param saleOrder 订单对象
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setOrderPrice(SaleOrder saleOrder) throws Exception {
        List<SaleOrderItem> saleOrderItemList = saleOrder.getSaleOrderItemList();
        Double totalAmount = 0.0;
        for (SaleOrderItem saleOrderItem : saleOrderItemList) {
            String itemType = saleOrderItem.getItemType();
            if ("Gift Item".equals(itemType)) {
                //如果是赠品，把政策价设置为null，把成交价，金额都设置为0
                saleOrderItem.setPolicyPrice(null);
                saleOrderItem.setNetPrice(0d);
                saleOrderItem.setAmount(0d);
                continue;
            }
            //政策价
            Double policyPrice = saleOrderItem.getPolicyPrice();
            //手工价
            Double manualPrice = saleOrderItem.getManualPrice();
            //促销价
            Double promotionPrice = saleOrderItem.getPromotionPrice();
            if (promotionPrice == null) {
                throw new ServiceException("POLICY-015");
            }
            Double num = saleOrderItem.getQty();

            if (manualPrice != null && manualPrice > 0.0) {
                totalAmount += manualPrice * num;
                continue;
            }

            if (policyPrice != null && policyPrice > 0.0) {
                totalAmount += policyPrice * num;
                continue;
            }
            totalAmount += promotionPrice * num;
        }
        //设置订单应付金额
        saleOrder.setOrderTotalAmount(totalAmount);
        Double orderAccount = saleOrder.getOrderAmount();
        //设置订单单品折扣金额
        saleOrder.setProdDiscount(orderAccount - totalAmount);
    }

    /**
     * @param policyListAttr 政策列表
     * @param policyType     政策类型
     * @param ruleType       规则类型
     * @param cndObjType     条件对象类型
     * @param cndObjSubType  条件对象子类型
     * @param circleFlag     循环标识 如果传入"" 标识不做筛选，如果传入N，标识筛选出条件循环标识不为Y的。
     *                       否则，如果传入的是Y，表示筛选出循环标识为Y的记录。
     * @return 满足条件的政策
     * @throws Exception 常规报错
     *                   HuangLJ
     *                   通过指定的类型，获取政策
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private List<Policy> getPolicyByTypes(List<Policy> policyListAttr, String policyType,
                                          String ruleType, String cndObjType, String cndObjSubType, String circleFlag) throws Exception {
        //通过fastjson生成一个新的对象。不然会影响后续的政策生成
        //复制一个新的
        String policyStr = JSON.toJSONString(policyListAttr);
        //复制一个新的
        List<Policy> policyList = JSON.parseArray(policyStr, Policy.class);
        for (int i = 0; i < policyList.size(); ++i) {
            //获取政策类型
            String curentPolicyType = policyList.get(i).getMajorType();
            if (!policyType.equals(curentPolicyType)) {
                policyList.remove(i);
                --i;
                continue;
            }
            //如果查询到对应的政策类型，往下走，查询对应的规则类型
            List<PcyRule> pcyRuleList = policyList.get(i).getRuleList();
            for (int j = 0; pcyRuleList != null && j < pcyRuleList.size(); ++j) {
                if (!ruleType.equals(pcyRuleList.get(j).getRuleType())) {
                    pcyRuleList.remove(j);
                    --j;
                    continue;
                }
                List<PcyCnd> pcyCndList = pcyRuleList.get(j).getConditionList();
                for (int x = 0; pcyCndList != null && x < pcyCndList.size(); ++x) {
                    //如果当前的条件类型满足要求，则返回当前的组合,包括规则结果
                    //如果条件子类型不为空，则也要判断条件子类型
                    if (!StringUtils.isNull(cndObjSubType)) {
                        if (!(cndObjType.equals(pcyCndList.get(x).getCndObjType())
                                || cndObjSubType.equals(pcyCndList.get(x).getCndObjSubType()))) {

                            pcyCndList.remove(x);
                            pcyRuleList.get(j).setResultList(null);
                            --x;
                        } else if (!"Y".equals(pcyCndList.get(x).getCirculated()) && "Y".equals(circleFlag)) {
                            //校验循环
                            pcyCndList.remove(x);
                            pcyRuleList.get(j).setResultList(null);
                            --x;
                        } else if ("Y".equals(pcyCndList.get(x).getCirculated()) && "N".equals(circleFlag)) {
                            //如果是非循环坎级的
                            pcyCndList.remove(x);
                            pcyRuleList.get(j).setResultList(null);
                            --x;
                        }
                    } else {
                        //如果对象子类型为空，则直接判断对象类型
                        if (!cndObjType.equals(pcyCndList.get(x).getCndObjType())) {
                            pcyCndList.remove(x);
                            pcyRuleList.get(j).setResultList(null);
                            --x;
                        } else if (!"Y".equals(pcyCndList.get(x).getCirculated()) && "Y".equals(circleFlag)) {
                            //校验循环
                            pcyCndList.remove(x);
                            pcyRuleList.get(j).setResultList(null);
                            --x;
                        } else if ("Y".equals(pcyCndList.get(x).getCirculated()) && "N".equals(circleFlag)) {
                            //如果是非循环坎级的
                            pcyCndList.remove(x);
                            pcyRuleList.get(j).setResultList(null);
                            --x;
                        }
                    }
                }
            }
            //判断，如果当前政策里面，已经没有规则了。则当前政策删除掉。
            if (policyList.get(i).getRuleList() == null || policyList.get(i).getRuleList().size() < 1) {
                policyList.remove(i);
                --i;
            }
        }

        //把政策拆开，确保每一条政策只有一个规则
        List<Policy> policyListRet = unpackPolicyList(policyList);

        //基于规则开始时间进行倒叙排列
//      sortPolicyListByRule(policyListRet);
        return policyListRet;
    }


    /**
     * HuangLJ 2018年07月02日
     *
     * @param policyList 政策列表
     * @return 拆开之后的政策
     * Comments 把政策拆开。确保每一个政策下面只有一个规则，便于排序
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private List<Policy> unpackPolicyList(List<Policy> policyList) throws Exception {
        List<Policy> policyListNew = new ArrayList<Policy>();

        for (Policy policy : policyList) {
            List<PcyRule> pcyRuleList = policy.getRuleList();
            for (PcyRule pcyRule : pcyRuleList) {
                //复制一个新的
                String policyStr = JSON.toJSONString(policy);
                Policy policyNew = JSON.parseObject(policyStr, Policy.class);

                //复制一个新的
                String ruleStr = JSON.toJSONString(pcyRule);
                PcyRule pcyRuleNew = JSON.parseObject(ruleStr, PcyRule.class);
                List<PcyRule> pcyRuleListnew = new ArrayList<>();
                pcyRuleListnew.add(pcyRuleNew);

                policyNew.setRuleList(pcyRuleListnew);

                policyListNew.add(policyNew);
            }
        }
        return policyListNew;
    }

    /**
     * HuangLJ 2018年07月02日
     *
     * @param policyList 政策列表
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void sortPolicyListByRule(List<Policy> policyList) throws Exception {
        policyList.sort((Policy policy1, Policy policy2) -> policy2.getRuleList().get(0).getStartDate()
                .compareTo(policy1.getRuleList().get(0).getStartDate()));
    }

    /**
     * HuangLJ
     * 通过指定的政策类型，设置订单行政策信息
     *
     * @param policyList 政策信息
     * @param saleOrder  订单对象
     * @throws Exception 常规
     */
    private void calculationSaleOrderItem(List<Policy> policyList, SaleOrder saleOrder) throws Exception {
        for (Policy policy : policyList) {
            List<PcyRule> pcyRuleList = policy.getRuleList();
            for (PcyRule pcyRule : pcyRuleList) {
                //条件
                List<PcyCnd> pcyCndList = pcyRule.getConditionList();
                //结果
                List<PcyResult> pcyResultList = pcyRule.getResultList();

                for (PcyCnd pcyCnd : pcyCndList) {
                    //规则类型
                    String ruleType = pcyRule.getRuleType();
                    //政策类型
                    String policyType = policy.getMajorType();
                    if ("StaircasePricing".equals(ruleType)) {
                        //坎级
                        if ("Buy Gifts".equals(policy.getMajorType())) {
                            //如果当政策类型是：买赠,走买赠的坎级逻辑
                            setRidgeBGScene(saleOrder, pcyCndList, pcyResultList, pcyRule.getRuleType());
                        } else {
                            //走非赠品的逻辑
                            setRidgeScene(saleOrder, pcyCndList, pcyResultList, policyType);
                        }
                    } else if ("ConditionalPricing".equals(ruleType)) {
                        //满减
                        if ("Buy Gifts".equals(policy.getMajorType())) {
                            //如果当政策类型是：买赠,走买赠的满减逻辑
                            setEnoughBGScene(saleOrder, pcyCnd, pcyResultList, pcyRule.getRuleType());
                        } else {
                            //走非赠品的逻辑
                            setEnoughScene(saleOrder, pcyCnd, pcyResultList, policyType);
                        }

                    }
                }
            }
        }
    }

    /**
     * HuangLJ
     * 计算订单头的政策信息
     *
     * @param policyList 政策列表
     * @param saleOrder  订单
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void calculationSaleOrderHead(List<Policy> policyList, SaleOrder saleOrder) throws Exception {
        boolean genPolicyFlag = saleOrder.isGeneratePolicyFlag();
        //如果已经生成过政策，则直接返回
        if (genPolicyFlag) {
            return;
        }
        for (Policy policy : policyList) {
            List<PcyRule> pcyRuleList = policy.getRuleList();
            for (PcyRule pcyRule : pcyRuleList) {
                List<PcyResult> pcyResultList = pcyRule.getResultList();
                //规则类型
                String ruleType = pcyRule.getRuleType();
                List<PcyCnd> pcyCndList = pcyRule.getConditionList();
                for (PcyCnd pcyCnd : pcyCndList) {
                    if ("StaircasePricing".equals(ruleType)) {
                        if ("Buy Gifts".equals(policy.getMajorType())) {
                            setGiftHead(pcyCndList, pcyCnd, pcyResultList, saleOrder, ruleType);
                        } else {
                            //坎级
                            setBradgeWholeOrderScene(pcyResultList, saleOrder, policy.getMajorType(), pcyCnd, ruleType);
                        }
                    } else if ("ConditionalPricing".equals(ruleType)) {
                        if ("Buy Gifts".equals(policy.getMajorType())) {
                            setGiftHead(pcyCndList, pcyCnd, pcyResultList, saleOrder, ruleType);
                        } else {
                            //满减
                            setEnoughWholeOrderScene(pcyResultList, saleOrder, policy.getMajorType(), pcyCnd, ruleType);
                        }
                    }
                }
            }
        }
    }

    /**
     * 设置满减的买赠订单行
     *
     * @param saleOrder     待设置的订单
     * @param pcyCnd        政策条件
     * @param pcyResultList 规则结果
     * @param ruleType      规则类型
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setEnoughBGScene(SaleOrder saleOrder, PcyCnd pcyCnd, List<PcyResult> pcyResultList, String ruleType) throws Exception {
        List<SaleOrderItem> saleOrderItemList = saleOrder.getSaleOrderItemList();
        List<SaleOrderItem> saleOrderItemList1 = new ArrayList<SaleOrderItem>();
        List<SaleOrderItem> saleOrderItemList2 = new ArrayList<SaleOrderItem>();
        List<SaleOrderItem> saleOrderItemList3 = new ArrayList<SaleOrderItem>();
        for (SaleOrderItem saleOrderItem : saleOrderItemList) {
            Boolean isGenerateGift = saleOrderItem.isGenerateGiftFlag();
            if (isGenerateGift) {
                //表示当前已经生成了赠品了，则继续。不走下面的生成逻辑。
                continue;
            }
            Double policyPrice = saleOrderItem.getPolicyPrice();
            //如果已经生成过政策，则略过
            if (policyPrice != null && policyPrice > 0d) {
                continue;
            }

            String itemType = saleOrderItem.getItemType();
            if ("Gift Item".equals(itemType)) {
                continue;
            }
            if ("Product".equals(pcyCnd.getCndObjType())) {
                //如果条件对象类型是产品
                if (pcyCnd.getProdId().equals(saleOrderItem.getProdId())) {
                    //比较,如果产品相同，则走产品的逻辑
                    List<SaleOrderItem> saleOrderItemListMid1 = setGift(null, pcyCnd, pcyResultList, saleOrder, saleOrderItem, ruleType, 0d);
                    saleOrderItemList1.addAll(saleOrderItemListMid1);
                    if (saleOrderItemListMid1.size() > 0) {
                        saleOrderItem.setGenerateGiftFlag(true);
                        this.currentPolicyCndIdList.add(saleOrderItem.getId() + "," + pcyCnd.getId());
                    }
                }
            } else if ("SingleProduct".equals(pcyCnd.getCndObjSubType())) {
                //如果条件对象类型为品牌，则走品牌的逻辑
                if (checkProductBrand(saleOrderItem.getProdId(), pcyCnd, pcyCnd.getCndObjType())) {
                    //满足品牌信息
                    //设置赠品信息
                    List<SaleOrderItem> saleOrderItemListMid2 = setGift(null, pcyCnd, pcyResultList, saleOrder, saleOrderItem, ruleType, 0d);
                    saleOrderItemList2.addAll(saleOrderItemListMid2);
                    if (saleOrderItemListMid2.size() > 0) {
                        saleOrderItem.setGenerateGiftFlag(true);
                        this.currentPolicyCndIdList.add(saleOrderItem.getId() + "," + pcyCnd.getId());
                    }
                }
            } else if ("MixProduct".equals(pcyCnd.getCndObjSubType())) {
                //产品品牌，组合
                if (checkProductBrand(saleOrderItem.getProdId(), pcyCnd, pcyCnd.getCndObjType())) {
                    Double num = getOrderItemBrandNum(saleOrderItemList, pcyCnd);
                    if (num != null) {
                        //如果数量大于登录条件的值。则往下走
                        //满足品牌信息
                        //设置赠品信息
                        saleOrderItemList3 = setGift(null, pcyCnd, pcyResultList, saleOrder, saleOrderItem, ruleType, num);
//                        saleOrderItemList3.addAll(saleOrderItemListMid3);
                        if (saleOrderItemList3.size() > 0) {
                            //把对应的行，都打上标记
                            String itemIdStr = setOrderItemGiftFlag(saleOrderItemList, pcyCnd);
                            this.currentPolicyCndIdList.add(itemIdStr + "," + pcyCnd.getId());
                        }
                    }
                }
            } else {
                throw new ServiceException("POLICY-016");
            }
        }
        //把得到的赠品，都添加到订单中。
        setOrderItem(saleOrder, saleOrderItemList1);
        setOrderItem(saleOrder, saleOrderItemList2);
        setOrderItem(saleOrder, saleOrderItemList3);
    }


    /**
     * 把传入的订单行加入到订单中，用来设置赠品
     *
     * @param saleOrder         订单
     * @param saleOrderItemList 订单行
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setOrderItem(SaleOrder saleOrder, List<SaleOrderItem> saleOrderItemList) throws Exception {
        for (SaleOrderItem saleOrderItem : saleOrderItemList) {
            SaleOrderItem saleOrderItemNew = (SaleOrderItem) BeanUtils.cloneBean(saleOrderItem);
            saleOrder.getSaleOrderItemList().add(saleOrderItemNew);
        }
    }

    /**
     * @param saleOrder     订单
     * @param pcyCndList    条件列表
     * @param pcyResultList 结果
     * @param ruleType      规则类型
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setRidgeBGScene(SaleOrder saleOrder, List<PcyCnd> pcyCndList, List<PcyResult> pcyResultList, String ruleType) throws Exception {

        List<SaleOrderItem> saleOrderItemList1 = new ArrayList<SaleOrderItem>();
        List<SaleOrderItem> saleOrderItemList2 = new ArrayList<SaleOrderItem>();
        List<SaleOrderItem> saleOrderItemList3 = new ArrayList<SaleOrderItem>();
        List<SaleOrderItem> saleOrderItemList = saleOrder.getSaleOrderItemList();
        for (SaleOrderItem saleOrderItem : saleOrderItemList) {
            Boolean isGenerateGift = saleOrderItem.isGenerateGiftFlag();
            if (isGenerateGift) {
                //表示当前已经生成了赠品了，则继续。不走下面的生成逻辑。
                continue;
            }

            Double policyPrice = saleOrderItem.getPolicyPrice();
            //如果已经生成过政策，则略过
            if (policyPrice != null && policyPrice > 0d) {
                continue;
            }

            String itemType = saleOrderItem.getItemType();
            if ("Gift Item".equals(itemType)) {
                continue;
            }
            for (PcyCnd pcyCnd : pcyCndList) {
                if ("Product".equals(pcyCnd.getCndObjType())) {
                    if (pcyCnd.getProdId().equals(saleOrderItem.getProdId())) {
                        //比较,如果产品相同，则走自己的逻辑，
                        List<SaleOrderItem> saleOrderItemListMid = setGift(pcyCndList, pcyCnd, pcyResultList, saleOrder, saleOrderItem, ruleType, 0d);
                        saleOrderItemList1.addAll(saleOrderItemListMid);
                        if (saleOrderItemListMid.size() > 0) {
                            saleOrderItem.setGenerateGiftFlag(true);
                            this.currentPolicyCndIdList.add(saleOrderItem.getId() + "," + pcyCnd.getId());
                        }
                    }
                } else if ("SingleProduct".equals(pcyCnd.getCndObjSubType())) {
                    //如果条件对象类型为品牌，则走品牌的逻辑
                    if (checkProductBrand(saleOrderItem.getProdId(), pcyCnd, pcyCnd.getCndObjType())) {
                        //满足品牌信息
                        //设置赠品信息
                        List<SaleOrderItem> saleOrderItemListMid = setGift(pcyCndList, pcyCnd, pcyResultList, saleOrder, saleOrderItem, ruleType, 0d);
                        saleOrderItemList2.addAll(saleOrderItemListMid);
                        if (saleOrderItemListMid.size() > 0) {
                            saleOrderItem.setGenerateGiftFlag(true);
                            this.currentPolicyCndIdList.add(saleOrderItem.getId() + "," + pcyCnd.getId());
                        }
                    }
                } else if ("MixProduct".equals(pcyCnd.getCndObjSubType())) {
                    //产品品牌，组合
                    if (checkProductBrand(saleOrderItem.getProdId(), pcyCnd, pcyCnd.getCndObjType())) {
                        Double num = getOrderItemBrandNum(saleOrderItemList, pcyCnd);
                        if (num != null) {
                            //如果数量大于登录条件的值。则往下走
                            //满足品牌信息
                            //设置赠品信息
                            List<SaleOrderItem> saleOrderItemListMid =
                                    setGift(pcyCndList, pcyCnd, pcyResultList, saleOrder, saleOrderItem, ruleType, num);
                            saleOrderItemList3.addAll(saleOrderItemListMid);
                            if (saleOrderItemListMid.size() > 0) {
                                saleOrderItem.setGenerateGiftFlag(true);
                                //把对应的行，都打上标记
                                String itemIdStr = setOrderItemGiftFlag(saleOrderItemList, pcyCnd);
                                this.currentPolicyCndIdList.add(itemIdStr + "," + pcyCnd.getId());
                            }
                        }
                    }
                } else {
                    throw new ServiceException("POLICY-016");
                }
            }
        }
        //把得到的赠品，都添加到订单中。
        setOrderItem(saleOrder, saleOrderItemList1);
        setOrderItem(saleOrder, saleOrderItemList2);
        setOrderItem(saleOrder, saleOrderItemList3);
    }

    /**
     * @param saleOrder     订单信息
     * @param pcyCnd        条件 ： 特价 满减 产品
     * @param pcyResultList 结果集
     * @param type          表示减价或者特价
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setEnoughScene(SaleOrder saleOrder, PcyCnd pcyCnd, List<PcyResult> pcyResultList, String type) throws Exception {
        List<SaleOrderItem> saleOrderItemList = saleOrder.getSaleOrderItemList();
        for (SaleOrderItem saleOrderItem : saleOrderItemList) {
            Double manualPrice = saleOrderItem.getManualPrice();
            if (manualPrice != null && manualPrice > 0) {
                //如果手工价大于0 ，则略过
                continue;
            }

            Double policyPrice1 = saleOrderItem.getPolicyPrice();
            if (policyPrice1 != null && policyPrice1 > 0d) {
                //如果当前订单行已经运用了政策，则略过
                continue;
            }
            if ("Product".equals(pcyCnd.getCndObjType())) {
                if (null != pcyCnd.getProdId() && pcyCnd.getProdId().equals(saleOrderItem.getProdId())) {
                    //表示单标签的订单行没有运用政策
                    Double num = pcyCnd.getVal();
                    Double qty = saleOrderItem.getQty();
                    if (num != null && qty != null && qty >= num) {
                        //如果订单行数量大于等于条件的数量，则可以运用政策。
                        for (PcyResult pcyResult : pcyResultList) {
                            setPrice(pcyResult, saleOrderItem, type);
                            this.currentPolicyCndIdList.add(saleOrderItem.getId() + "," + pcyCnd.getId());
                        }
                    }
                }
            } else if ("SingleProduct".equals(pcyCnd.getCndObjSubType())) {
                //如果是产品品牌 ，同时条件二级类型为单品
                if (checkProductBrand(saleOrderItem.getProdId(), pcyCnd, pcyCnd.getCndObjType())) {
                    //表示单标签的订单行没有运用政策
                    Double num = pcyCnd.getVal();
                    Double qty = saleOrderItem.getQty();
                    if (num != null && qty != null && qty >= num) {
                        //如果订单行数量大于等于条件的数量，则可以运用政策。
                        for (PcyResult pcyResult : pcyResultList) {
                            setPrice(pcyResult, saleOrderItem, type);
                            this.currentPolicyCndIdList.add(saleOrderItem.getId() + "," + pcyCnd.getId());
                        }
                    }
                }
            } else if ("MixProduct".equals(pcyCnd.getCndObjSubType())) {
                //如果是产品品牌 ，同时条件二级类型为按产品组合
                Double num = getOrderItemBrandNum(saleOrderItemList, pcyCnd);
                Double pcyVal = pcyCnd.getVal();
                if (pcyVal == null || num == null) {
                    continue;
                }
                if (num >= pcyCnd.getVal()) {
                    //如果已经存在满足条件，则设置当前行list上面，满足条件的价格
                    for (PcyResult pcyResult : pcyResultList) {
                        String itemIdStr = setOrderItemBrandPrice(saleOrderItemList, pcyCnd, pcyResult, type);
                        this.currentPolicyCndIdList.add(itemIdStr + "," + pcyCnd.getId());
                    }
                }
            }
        }
    }

    /**
     * @param pcyResultList 规则结果
     * @param saleOrder     订单信息
     * @param type          政策类型
     * @param pcyCnd        规则条件
     * @param ruleType      规则类型
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setEnoughWholeOrderScene(List<PcyResult> pcyResultList, SaleOrder saleOrder,
                                          String type, PcyCnd pcyCnd, String ruleType) throws Exception {
        //如果是整单，则走整单的逻辑
        Double orderAmount = saleOrder.getOrderTotalAmount();
        Double pcyVal = pcyCnd.getVal();
        if (orderAmount == null || pcyVal == null) {
            return;
        }

        if (orderAmount >= pcyVal) {
            for (PcyResult pcyResult : pcyResultList) {
                setPriceHead(pcyResult, saleOrder, type, pcyCnd, ruleType);
                this.currentPolicyCndIdList.add("," + pcyCnd.getId());
            }
        }
    }

    /**
     * @param pcyResultList 规则结果
     * @param saleOrder     订单
     * @param type          政策类型
     * @param pcyCnd        规则条件
     * @param ruleType      规则类型
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setBradgeWholeOrderScene(List<PcyResult> pcyResultList, SaleOrder saleOrder, String type,
                                          PcyCnd pcyCnd, String ruleType) throws Exception {
        //如果是整单，则走整单的逻辑
        Double orderAmount = saleOrder.getOrderTotalAmount();
        Double maxNum = pcyCnd.getCndMaximum();
        Double minNum = pcyCnd.getCndMinimum();
        int cndSeq = pcyCnd.getSeq();
        if (minNum == null) {
            return;
        }
        boolean flagOne = (orderAmount >= minNum) ? true : false;
        boolean flagTwo = (maxNum == null || orderAmount < maxNum) ? true : false;
        if (flagOne && flagTwo) {
            for (PcyResult pcyResult : pcyResultList) {
                int seq = pcyResult.getSeq();
                if (seq == cndSeq) {
                    setPriceHead(pcyResult, saleOrder, type, pcyCnd, ruleType);
                    this.currentPolicyCndIdList.add("," + pcyCnd.getId());
                }
            }
        }
    }


    /**
     * @param saleOrder     待设置的销售订单
     * @param pcyCndList    政策条件
     * @param pcyResultList 规则结果
     * @param type          条件类型，需要通过类型取不同的逻辑，设置
     * @throws Exception s
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setRidgeScene(SaleOrder saleOrder, List<PcyCnd> pcyCndList, List<PcyResult> pcyResultList, String type) throws Exception {
        List<SaleOrderItem> saleOrderItemList = saleOrder.getSaleOrderItemList();
        for (PcyCnd pcyCnd : pcyCndList) {
            for (SaleOrderItem saleOrderItem : saleOrderItemList) {
                //如果当前的订单行手动改价>0,则不走逻辑非赠品的逻辑
                Double manualPrice = saleOrderItem.getManualPrice();
                if (manualPrice != null && manualPrice > 0d) {
                    continue; //如果手工价大于0 ，则略过
                }

                Double policyPrice1 = saleOrderItem.getPolicyPrice();
                if (policyPrice1 != null && policyPrice1 > 0d) {
                    continue; //如果当前订单行已经运用了政策，则略过
                }

                if ("Product".equals(pcyCnd.getCndObjType())) {
                    //产品id是否相同
                    boolean prodIdFlag = (saleOrderItem.getProdId().equals(pcyCnd.getProdId())) ? true : false;
                    //价格不为空
                    boolean policyPriceFlag = (saleOrderItem.getPolicyPrice() == null || saleOrderItem.getPolicyPrice() == 0d) ? true : false;
                    if (prodIdFlag && policyPriceFlag) {
                        //如果订单行产品Id 等于条件的产品id。则校验是否满足条件，满足则走政策
                        Double mixNum = pcyCnd.getCndMinimum();
                        Double maxNum = pcyCnd.getCndMaximum();
                        Double qty = saleOrderItem.getQty();
                        if (mixNum == null || qty == null) {
                            continue;
                        }
                        boolean flagMix = (qty >= mixNum) ? true : false;
                        boolean flagMax = (maxNum == null || qty < maxNum) ? true : false;
                        if (flagMix && flagMax) {
                            //表示可以运用这个政策
                            for (PcyResult pcyResult : pcyResultList) {
                                if (pcyResult.getSeq().equals(pcyCnd.getSeq())) {
                                    setPrice(pcyResult, saleOrderItem, type);
                                    this.currentPolicyCndIdList.add(saleOrderItem.getId() + "," + pcyCnd.getId());
                                }
                            }
                        }
                    }
                } else if ("SingleProduct".equals(pcyCnd.getCndObjSubType())) {
                    //如果是产品品牌 ，同时条件二级类型为单品
                    boolean productBrandFlag = checkProductBrand(saleOrderItem.getProdId(), pcyCnd, pcyCnd.getCndObjType());
                    boolean priceFlag = (saleOrderItem.getPolicyPrice() == null || saleOrderItem.getPolicyPrice() == 0d) ? true : false;
                    if (productBrandFlag && priceFlag) {
                        //如果订单行产品Id 等于条件的产品id。则校验是否满足条件，满足则走政策
                        Double mixNum = pcyCnd.getCndMinimum();
                        Double maxNum = pcyCnd.getCndMaximum();
                        Double qty = saleOrderItem.getQty();
                        if (mixNum == null || qty == null) {
                            continue;
                        }
                        boolean mixNumFlag = (qty >= mixNum) ? true : false;
                        boolean maxNumFlag = (maxNum == null || qty < maxNum) ? true : false;
                        if (mixNumFlag && maxNumFlag) {
                            //表示可以运用这个政策
                            for (PcyResult pcyResult : pcyResultList) {
                                if (pcyResult.getSeq().equals(pcyCnd.getSeq())) {
                                    this.currentPolicyCndIdList.add(saleOrderItem.getId() + "," + pcyCnd.getId());
                                    setPrice(pcyResult, saleOrderItem, type);
                                }
                            }
                        }
                    }
                } else if ("MixProduct".equals(pcyCnd.getCndObjSubType())) {
                    //如果是产品品牌 ，同时条件二级类型为按产品组合
                    Double mixNum = pcyCnd.getCndMinimum();
                    if (mixNum == null) {
                        continue;
                    }
                    Double maxNum = pcyCnd.getCndMaximum();
                    Double num = getOrderItemBrandNum(saleOrderItemList, pcyCnd);
                    boolean oneFlag = (num >= mixNum) ? true : false;
                    boolean twoFlag = (maxNum == null || num < maxNum) ? true : false;
                    if (oneFlag && twoFlag) {
                        //如果已经存在满足条件，则设置当前行list上面，满足条件的价格
                        for (PcyResult pcyResult : pcyResultList) {
                            if (pcyResult.getSeq().equals(pcyCnd.getSeq())) {
                                String itemIdStr = setOrderItemBrandPrice(saleOrderItemList, pcyCnd, pcyResult, type);
                                this.currentPolicyCndIdList.add(itemIdStr + "," + pcyCnd.getId());
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * HuangLJ
     * 计算订单行的政策价格
     *
     * @param pcyResult     规则结果
     * @param saleOrderItem 订单行
     * @param type          政策类型
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setPrice(PcyResult pcyResult, SaleOrderItem saleOrderItem, String type) throws Exception {
        //特价
        String specialOffer = "Special Offer";
        //减价
        String priceReduction = "PriceReduction";
        //折扣
        String priceDiscount = "PriceDiscount";
        if (specialOffer.equals(type)) {
            //如果是特价，直接把结果写到政策价
            saleOrderItem.setPolicyPrice(pcyResult.getQty());
        } else if (priceReduction.equals(type)) {
            //如果是减价，计算出结果写入
            Double promotionPrice = saleOrderItem.getPromotionPrice() == null ? 0d : saleOrderItem.getPromotionPrice();
            Double pcyResQty = pcyResult.getQty();
            if (pcyResQty == null) {
                return;
            }
            saleOrderItem.setPolicyPrice(promotionPrice - pcyResQty);
        } else if (priceDiscount.equals(type)) {
            //折扣
            Double promotionPrice = saleOrderItem.getPromotionPrice() == null ? 0d : saleOrderItem.getPromotionPrice();
            Double pcyResQty = pcyResult.getQty();
            if (pcyResQty == null) {
                return;
            }
            saleOrderItem.setPolicyPrice(promotionPrice * (pcyResQty / 100));
        }
    }


    /**
     * HuangLJ
     * 计算订单行的政策价格
     *
     * @param pcyResult 规则结果
     * @param saleOrder 订单头
     * @param type      政策类型
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setPriceHead(PcyResult pcyResult, SaleOrder saleOrder, String type, PcyCnd pcyCnd, String ruleType) throws Exception {
        //如果是折扣，计算出结果写入
        Double orderAmount = saleOrder.getOrderTotalAmount();
        Double pcyResultQty = pcyResult.getQty();
        Double pcyVal = pcyCnd.getVal();

        if (pcyResultQty == null || orderAmount == null) {
            return;
        }

        Boolean policyFlag = saleOrder.isGeneratePolicyFlag();
        if (policyFlag) {
            //如果已经生成了政策，则略过
            return;
        }
        //减价
        String priceReduction = "PriceReduction";
        String flag = "Y";
        String staircasePricing = "StaircasePricing";
        String priceDiscount = "PriceDiscount";
        if (priceReduction.equals(type)) {
            //减价
            if (!flag.equals(pcyCnd.getCirculated())) {
                //是否循环
                //坎级
                if (staircasePricing.equals(ruleType)) {
                    //如果是减价，计算出结果写入整单折扣
                    saleOrder.setOrderDiscount(pcyResultQty);
                    saleOrder.setGeneratePolicyFlag(true);
                }
            } else {
                String conditionalPricing = "ConditionalPricing";
                //是否循环
                if (pcyVal == null) {
                    return;
                }
                if (staircasePricing.equals(ruleType)) {
                    //坎级
                    //如果是减价，计算出结果写入整单折扣
                    saleOrder.setOrderDiscount(pcyResultQty);
                    saleOrder.setGeneratePolicyFlag(true);
                } else if (conditionalPricing.equals(ruleType)) {
                    //满减
                    Double cirTime = orderAmount / pcyVal;
                    cirTime = Math.floor(cirTime);
                    saleOrder.setOrderDiscount(pcyResultQty * cirTime);
                    saleOrder.setGeneratePolicyFlag(true);
                }
            }
        } else if (priceDiscount.equals(type)) {
            //如果是折扣，计算出结果写入整单折扣
            saleOrder.setOrderDiscount(orderAmount - (orderAmount * (pcyResultQty / 100)));
            saleOrder.setGeneratePolicyFlag(true);
        }
    }

    /**
     * 设置赠品，吧赠品信息写入到订单行中
     * 如果为满减，必须传入参数为 pcyCnd， pcyResultList， saleOrder， saleOrderItem， ruleType
     * 如果为坎级，必须传入的参数为 pcyCndList， pcyResultList， saleOrder， saleOrderItem， ruleType
     *
     * @param pcyCndList    条件列表
     * @param pcyCnd        条件
     * @param pcyResultList 结果列表
     * @param saleOrder     订单
     * @param saleOrderItem 订单行
     * @param ruleType      规则类型
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private List<SaleOrderItem> setGift(List<PcyCnd> pcyCndList, PcyCnd pcyCnd, List<PcyResult> pcyResultList, SaleOrder saleOrder,
                                        SaleOrderItem saleOrderItem, String ruleType, Double numAtr) throws Exception {
        List<SaleOrderItem> saleOrderItemList = new ArrayList<>();
        String conditionalPricing = "ConditionalPricing";
        String staircasePricing = "StaircasePricing";
        if (conditionalPricing.equals(ruleType)) {
            //调用函数设置满减场景下的赠品
            setGiftConditional(pcyResultList, saleOrderItem, saleOrder, numAtr, pcyCnd, saleOrderItemList);
        } else if (staircasePricing.equals(ruleType)) {
            //调用函数设置坎级场景下的赠品
            setGiftStaircase(pcyResultList, saleOrderItem, saleOrder, numAtr, saleOrderItemList, pcyCndList);
        }
        return saleOrderItemList;
    }

    /**
     * @auther HuangLJ
     * @date 2018/11/5 11:47 AM
     * @comments 设置赠品 ，满减
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setGiftConditional(List<PcyResult> pcyResultList, SaleOrderItem saleOrderItem,
                                    SaleOrder saleOrder, Double numAtr, PcyCnd pcyCnd,
                                    List<SaleOrderItem> saleOrderItemList) throws Exception {
        //满减
        for (PcyResult pcyResult : pcyResultList) {
            Long productId = pcyResult.getProdId();
            if (productId == null) {
                productId = saleOrderItem.getProdId();
            }
            Long priceId = saleOrder.getPriceListId();
            Long orderId = saleOrder.getId();

            //订单行上面的产品数量
            Double itemProdNum = saleOrderItem.getQty();
            if (numAtr != null && numAtr > 0d) {
                itemProdNum = numAtr;
            }
            //政策结果上面的产品数量
            Double pcyResultQty = pcyResult.getQty();
            Double numCnd = pcyCnd.getVal();

            if (numCnd == null || pcyResultQty == null || itemProdNum == null) {
                continue;
            }

            if (itemProdNum >= numCnd) {
                //如果数量大于等于
                Double num = Math.floor(itemProdNum / numCnd);
                //生成新赠品行
                SaleOrderItem saleOrderItemNew = generateGiftOrdItem(productId, priceId, orderId, num * pcyResultQty);
                saleOrderItemList.add(saleOrderItemNew);
                saleOrderItem.setGenerateGiftFlag(true);
            }
        }
    }

    /**
     * @auther HuangLJ
     * @date 2018/11/5 11:57 AM
     * @comments 设置坎级情况下的赠品
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setGiftStaircase(List<PcyResult> pcyResultList, SaleOrderItem saleOrderItem, SaleOrder saleOrder,
                                  Double numAtr, List<SaleOrderItem> saleOrderItemList, List<PcyCnd> pcyCndList) throws Exception {
        //坎级
        for (PcyCnd pcyCnd1 : pcyCndList) {
            Boolean giftFlag = saleOrderItem.isGenerateGiftFlag();
            if (giftFlag) {
                continue;
            }
            Double minNum = pcyCnd1.getCndMinimum();
            Double maxNum = pcyCnd1.getCndMaximum();

            Double qty = saleOrderItem.getQty();
            if (numAtr != null && numAtr != 0d) {
                qty = numAtr;
            }
            Double val = pcyCnd1.getVal();
            if (minNum == null || qty == null || val == null) {
                continue; //如果只为空，则直接返回。防止报错
            }

            Double cirTime = Math.floor(qty / val);

            int seq = pcyCnd1.getSeq();
            boolean flagOne = (qty >= minNum) ? true : false;
            boolean flagTwo = (maxNum == null || qty < maxNum) ? true : false;
            if (flagOne && flagTwo) {
                //满足条件，设置，结果
                for (PcyResult pcyResult : pcyResultList) {
                    if (seq == pcyResult.getSeq()) {
                        Long productId = pcyResult.getProdId();

                        Double retQty = pcyResult.getQty();
                        if (retQty == null) {
                            continue;
                        }

                        if (productId == null) {
                            productId = saleOrderItem.getProdId();
                        }
                        Long priceId = saleOrder.getPriceListId();
                        Long orderId = saleOrder.getId();
                        Double num;
                        if ("Y".equals(pcyCnd1.getCirculated())) {
                            //如果是循环坎级
                            num = pcyResult.getQty() * cirTime;
                        } else {
                            //非循环坎级
                            num = pcyResult.getQty();
                        }
                        //生成新赠品行
                        SaleOrderItem saleOrderItemNew = generateGiftOrdItem(productId, priceId, orderId, num);
                        saleOrderItemList.add(saleOrderItemNew);
                        saleOrderItem.setGenerateGiftFlag(true);
                    }
                }
            }
        }
    }

    /**
     * 设置赠品，吧赠品信息写入到订单行中
     * 如果为满减，必须传入参数为 pcyCnd， pcyResultList， saleOrder， saleOrderItem， ruleType
     * 如果为坎级，必须传入的参数为 pcyCndList， pcyResultList， saleOrder， saleOrderItem， ruleType
     *
     * @param pcyCndList    条件列表
     * @param pcyCnd        条件
     * @param pcyResultList 结果列表
     * @param saleOrder     订单
     * @param ruleType      规则类型
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private void setGiftHead(List<PcyCnd> pcyCndList, PcyCnd pcyCnd, List<PcyResult> pcyResultList,
                             SaleOrder saleOrder, String ruleType) throws Exception {
        if (saleOrder.isGeneratePolicyFlag()) {
            return;
        }
        Double orderAmount = saleOrder.getOrderTotalAmount();
        Double pcyCndVal = pcyCnd.getVal();
        if (orderAmount == null) {
            //如果值为空，则直接返回，防止报错
            return;
        }
        //是否循环
        String cirFlag = pcyCnd.getCirculated();
        String conditionalPricing = "ConditionalPricing";
        String staircasePricing = "StaircasePricing";
        if (conditionalPricing.equals(ruleType)) {
            //满减
            if (pcyCndVal == null) {
                return;
            }
            if (orderAmount >= pcyCndVal) {
                for (PcyResult pcyResult : pcyResultList) {
                    Double resultQty = pcyResult.getQty();
                    Long productId = pcyResult.getProdId();
                    Long priceListId = saleOrder.getPriceListId();
                    if (productId == null) {
                        //如果没有设置赠品信息，则把条件的产品给它
                        return;
                    }
                    //循环次数
                    Double cirTime = Math.floor(orderAmount / pcyCndVal);
                    SaleOrderItem saleOrderItemNew = generateGiftOrdItem(productId, priceListId, saleOrder.getId(), resultQty * Math.floor(cirTime));
                    saleOrder.getSaleOrderItemList().add(saleOrderItemNew);
                    saleOrder.setGeneratePolicyFlag(true);
                    this.currentPolicyCndIdList.add("," + pcyCnd.getId());
                }
            }
        } else if (staircasePricing.equals(ruleType)) {
            //坎级
            for (PcyCnd pcyCnd1 : pcyCndList) {
                Boolean genGiftFlag = saleOrder.isFirstFlag();
                if (genGiftFlag) {
                    return;
                }
                Double minNum = pcyCnd1.getCndMinimum();
                if (minNum == null || minNum < 0) {
                    //如果最小值为空或者小于0 则直接返回
                    return;
                }
                Double maxNum = pcyCnd1.getCndMaximum();


                int seq = pcyCnd1.getSeq();
                boolean flagOne = (orderAmount >= minNum) ? true : false;
                boolean flagTwo = (maxNum == null || orderAmount < maxNum) ? true : false;
                if (flagOne && flagTwo) {
                    for (PcyResult pcyResult : pcyResultList) {
                        if (seq == pcyResult.getSeq()) {
                            Long productId = pcyResult.getProdId();

                            if (productId == null) {
                                //如果没有设置赠品信息，则把条件的赠品给它
                                return;
                            }

                            Long priceId = saleOrder.getPriceListId();
                            Long orderId = saleOrder.getId();
                            Double num;
                            if ("Y".equals(cirFlag)) {
                                //如果是循环坎级
                                if (pcyCndVal == null) {
                                    return;
                                }
                                Double cirTime = Math.floor(orderAmount / pcyCndVal);
                                //循环次数
                                num = pcyResult.getQty() * cirTime;
                            } else {
                                //非循环坎级
                                num = pcyResult.getQty();
                            }
                            //生成新赠品行
                            SaleOrderItem saleOrderItemNew = generateGiftOrdItem(productId, priceId, orderId, num);
                            //把行信息加入到订单中
                            saleOrder.getSaleOrderItemList().add(saleOrderItemNew);
                            saleOrder.setGeneratePolicyFlag(true);
                            this.currentPolicyCndIdList.add("," + pcyCnd1.getId());
                        }
                    }
                }
            }
        }
    }


    /**
     * 校验订单的产品是否属于对应政策行条件上的品牌
     *
     * @param productId  产品Id
     * @param pcyCnd     条件
     * @param cndObjtype 条件对象类型，（系列或者品牌）
     * @return 返回boolean类型
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private Boolean checkProductBrand(Long productId, PcyCnd pcyCnd, String cndObjtype) throws Exception {
        //校验产品的品牌和和条件品牌是否一致。一致返回真，否则返回假
        Product productQuery = new Product();
        productQuery.setId(productId);
        Product product = productService.queryById(productQuery);
        if (product == null) {
            throw new ServiceException("POLICY-017",productId.toString());
        }
        String brandValue = pcyCnd.getBrandValue();
        String brandType = pcyCnd.getBrandType();
        return brandFlag(product, brandValue, brandType, cndObjtype);
    }

    /**
     * Hlj 2018年06月01日 递归查询当前的产品品牌或者系列。看看是不是满足条件
     *
     * @param product    产品信息
     * @param brandValue 品牌或者系列的值列表
     * @param brandType  品牌或者系列值列表类型
     * @param type       类型 （表示品牌或者系列）
     * @return bool值，表示是否匹配的上
     * @throws Exception 常规抛错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private Boolean brandFlag(Product product, String brandValue, String brandType, String type) throws Exception {
        if (matchValue(type, product, brandValue, brandType)) {
            //如果传入的值已经能匹配上了，直接返回真
            return true;
        }
        //查询出当前的类型和独立语言代码对应的子
        ListOfValue currentListOfValueQuery = new ListOfValue();
        currentListOfValueQuery.setParentVal(brandValue);
        currentListOfValueQuery.setParentType(brandType);
        currentListOfValueQuery.setTotalFlag(true);
        currentListOfValueQuery.setPageFlag(false);
        List<ListOfValue> currentListOfValueList = basicCommonMapper.queryByExamplePage(currentListOfValueQuery);

        //遍历查询出来的子
        for (ListOfValue listOfValue : currentListOfValueList) {
            String childValue = listOfValue.getVal();
            String childType = listOfValue.getType();
            //递归调用，如果返回的是true，则表示存在。直接返回真
            if (brandFlag(product, childValue, childType, type)) {
                return true;
            }
        }
        //当所有的逻辑都执行完之后，还没有被返回，表示当前已经没有刻匹配的。直接返回逻辑假
        return false;
    }

    /**
     * @param type       类型 （表示品牌或者系列）
     * @param product    产品信息
     * @param brandValue 品牌或者系列的值列表
     * @param brandType  品牌或者系列值列表类型
     * @return bool值，表示是否匹配的上
     * @throws Exception 常规抛错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private boolean matchValue(String type, Product product, String brandValue, String brandType) throws Exception {
        String productBrand = "ProductBrand";
        String prodThdBrand = "PROD_THD_BRAND";
        String prodSecBrand1 = "PROD_SEC_BRAND";
        String rodBrand = "ROD_BRAND";
        String productSeries = "ProductSeries";
        if (productBrand.equals(type)) {
            //产品品牌一级
            String prodBrand = product.getProdBrand();
            //产品品牌二级
            String prodSecBrand = product.getProdSecBrand();
            //产品品牌 三级
            String prodThirdBrand = product.getProdThirdBrand();

            if (prodThdBrand.equals(brandType) && brandValue.equals(prodThirdBrand)) {
                return true;
            }
            if (prodSecBrand1.equals(brandType) && brandValue.equals(prodSecBrand)) {
                return true;
            }
            if (rodBrand.equals(brandType) && brandValue.equals(prodBrand)) {
                return true;
            }
        } else if (productSeries.equals(type)) {
            //产品系列 一级
            String prodMatSeries = product.getProdMatSeries();
            //产品系列 二级
            String prodSecSeries = product.getProdSecSeries();
            //产品系列 三级
            String prodThirdSeries = product.getProdThirdSeries();

            String prodMatSeriesStr = "PROD_MAT_SERIES";
            String prodSecSeriesStr = "PROD_SEC_SERIES";
            String prodThdSeriesStr = "PROD_THD_SERIES";

            if (prodMatSeriesStr.equals(brandType) && brandValue.equals(prodMatSeries)) {
                return true;
            }
            if (prodSecSeriesStr.equals(brandType) && brandValue.equals(prodSecSeries)) {
                return true;
            }
            if (prodThdSeriesStr.equals(brandType) && brandValue.equals(prodThirdSeries)) {
                return true;
            }

        } else {
            return false;
        }
        return false;
    }

    /**
     * HuangLJ 2018年05月24日
     * 校验
     *
     * @param type       类型，ProductSeries 系列 ， ProductBrand 品牌
     * @param brandType  值列表类型
     * @param brandValue 值列表值
     * @param product    产品对象
     * @throws Exception 报错
     */
    private void checkBSAll(String type, String brandType, String brandValue, Product product) throws Exception {
//        if ("ProductBrand".equals(type)) {
//
//        } else if ("ProductSeries".equals(type)) {
//
//        }
    }

    /**
     * HuangLJ 获取订单行上面，某一产品品牌或系列的数量的数量 2018年05月22日
     *
     * @param saleOrderItemList 订单行列表
     * @param pcyCnd            条件
     * @return 数量
     * @throws Exception 常规抛错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private Double getOrderItemBrandNum(List<SaleOrderItem> saleOrderItemList, PcyCnd pcyCnd) throws Exception {
        Double num = 0.0;
        for (SaleOrderItem saleOrderItem : saleOrderItemList) {
            if (saleOrderItem.getPromotionPrice() != null && saleOrderItem.getPolicyPrice() != 0d) {
                //如果已经运用了政策，则不做累计
                continue;
            }
            String itemType = saleOrderItem.getItemType();
            Double qty = saleOrderItem.getQty();
            if (qty == null) {
                continue;
            }
            if ("Gift Item".equals(itemType)) {
                //如果是赠品，则不要计算
                continue;
            }
            if ("ProductBrand".equals(pcyCnd.getCndObjType())) {
                if (checkProductBrand(saleOrderItem.getProdId(), pcyCnd, pcyCnd.getCndObjType())) {
                    num = num + qty;
                }
            } else if ("ProductSeries".equals(pcyCnd.getCndObjType())) {
                if (checkProductBrand(saleOrderItem.getProdId(), pcyCnd, pcyCnd.getCndObjType())) {
                    num = num + qty;
                }
            }
        }
        return num;
    }

    /**
     * HuangLJ 设置基于全品牌或者系列的的订单价格 2018年05月22日
     *
     * @param saleOrderItemList 订单行列表
     * @param pcyCnd            条件
     * @param pcyResult         结果
     * @param type              政策类型
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private String setOrderItemBrandPrice(List<SaleOrderItem> saleOrderItemList, PcyCnd pcyCnd,
                                          PcyResult pcyResult, String type) throws Exception {
        StringBuilder orderItemIdStr = new StringBuilder();
        for (SaleOrderItem saleOrderItem : saleOrderItemList) {
            if (saleOrderItem.getPromotionPrice() != null && saleOrderItem.getPolicyPrice() != 0d) {
                //如果已经运用了政策，则不做累计
                continue;
            }
            String itemType = saleOrderItem.getItemType();
            if ("Gift Item".equals(itemType)) {
                //如果是赠品，则不要计算
                continue;
            }
            if (checkProductBrand(saleOrderItem.getProdId(), pcyCnd, pcyCnd.getCndObjType())) {
                //设置价格
                setPrice(pcyResult, saleOrderItem, type);
                Boolean orderItemIdStrNotNull = orderItemIdStr.length() > 0;
                if (orderItemIdStrNotNull) {
                    orderItemIdStr.append(";").append(saleOrderItem.getId());
                } else {
                    orderItemIdStr.append(saleOrderItem.getId());
                }
            }
        }
        return orderItemIdStr.toString();
    }

    /**
     * 设置行上面的记录
     *
     * @param saleOrderItemList 订单行List
     * @param pcyCnd            政策条件
     * @throws Exception 设置订单行列表中，对应的行为已生成赠品
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private String setOrderItemGiftFlag(List<SaleOrderItem> saleOrderItemList, PcyCnd pcyCnd) throws Exception {
        StringBuilder itemIdStr = new StringBuilder();
        for (SaleOrderItem saleOrderItem : saleOrderItemList) {
            String itemType = saleOrderItem.getItemType();
            if ("Gift Item".equals(itemType)) {
                continue;
            }
            if (saleOrderItem.isGenerateGiftFlag()) {
                continue;
            }
            if (checkProductBrand(saleOrderItem.getProdId(), pcyCnd, pcyCnd.getCndObjType())) {
                saleOrderItem.setGenerateGiftFlag(true);
                Boolean itemIdStrIsNull = itemIdStr.length() <= 0;
                if (itemIdStrIsNull) {
                    itemIdStr.append(saleOrderItem.getId());
                } else {
                    itemIdStr.append(";").append(saleOrderItem.getId());
                }

            }
        }
        return itemIdStr.toString();
    }


    /**
     * 通过产品Id和价格生成赠品
     *
     * @param productId   产品Id
     * @param priceListId 价格表Id
     * @param orderId     订单id
     * @param num         数量
     * @return 赠品订单行记录
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private SaleOrderItem generateGiftOrdItem(Long productId, Long priceListId, Long orderId, Double num) throws Exception {
        //生成赠品订单行记录
        Product productQuery = new Product();
        productQuery.setId(productId);
        Product product = productService.queryById(productQuery);
        if (product == null) {
            throw new ServiceException("POLICY-018",productId.toString());
        }
        PriceListItem priceListItemQuery = new PriceListItem();
        priceListItemQuery.setHeadId(priceListId);
        priceListItemQuery.setProdId(productId);
        List<PriceListItem> priceListItemList = priceListItemService.queryByProdId(priceListItemQuery);
        //促销价
        Double promoPrice = 0d;
        //原价
        Double basePrice = 0d;
        for (PriceListItem priceListItem : priceListItemList) {
            promoPrice = priceListItem.getPromoPrice();
            basePrice = priceListItem.getPrice();
        }
        SaleOrderItem saleOrderItem = new SaleOrderItem();
        saleOrderItem.setItemType("Gift Item");
        saleOrderItem.setPolicyPrice(0d);
        saleOrderItem.setPromotionPrice(promoPrice);
        saleOrderItem.setBasePrice(basePrice);
        //成交价
        Double netPrice = 0d;
        saleOrderItem.setNetPrice(netPrice);
        saleOrderItem.setOrderId(orderId);
        saleOrderItem.setHeadId(orderId);
        saleOrderItem.setProdId(productId);
        saleOrderItem.setProdSmallImagePath(product.getProdSmallImagePath());
        saleOrderItem.setProdImagePath(product.getProdImagePath());
        saleOrderItem.setProdCode(product.getProdCode());
        saleOrderItem.setProdName(product.getProdName());
        saleOrderItem.setProdBrand(product.getProdBrand());
        saleOrderItem.setProdSecBrand(product.getProdSecBrand());
        saleOrderItem.setProdMatSeries(product.getProdMatSeries());
        String unit = product.getProdUnit();
        saleOrderItem.setProdUnit(unit);

        num = Math.floor(num);
        saleOrderItem.setQty(num);
        return saleOrderItem;
    }


    /**
     * HuangLJ 2018年07月02日
     *
     * @param policyList             政策列表
     * @param currentPolicyCndIdList 条件Id列表
     * @param saleOrder              订单信息
     * @return 返回当前生成的显示信息
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private String getPolicyMsg(List<Policy> policyList, SaleOrder saleOrder, List<String> currentPolicyCndIdList) throws Exception {
        JSONObject jsonObjAll = new JSONObject();
        JSONArray jsonArrayHead = new JSONArray();
        JSONArray jsonArrayLine = new JSONArray();
        for (Policy policy : policyList) {
            for (String currentIdStr : currentPolicyCndIdList) {
                String[] strArr = currentIdStr.split(",");
                if (StringUtils.isNull(strArr[0])) {
                    PcyRule pcyRule = getPcyRule(policy, strArr[1]);
                    //首先设置头政策
                    if (pcyRule != null) {
                        JSONObject jsonObj = new JSONObject();
                        jsonObj.put("policyName", pcyRule.getPcyName());
                        jsonObj.put("ruleName", pcyRule.getRuleName());
                        jsonObj.put("type", policy.getMajorType());
                        //整单优惠
                        jsonObj.put("num", saleOrder.getOrderDiscount());
                        jsonArrayHead.add(jsonObj);
                    }
                } else {
                    String[] itemIdAttr = strArr[0].split(";");
                    PcyRule pcyRule = getPcyRule(policy, strArr[1]);
                    for (String itemId : itemIdAttr) {
                        if (pcyRule != null) {
                            //表示当前为产品类型
                            List<SaleOrderItem> saleOrderItemList = saleOrder.getSaleOrderItemList();
                            for (SaleOrderItem saleOrderItem : saleOrderItemList) {
                                if (saleOrderItem.getId() != null && saleOrderItem.getId().equals(itemId)) {
                                    JSONObject jsonObj = new JSONObject();
                                    jsonObj.put("policyName", pcyRule.getPcyName());
                                    jsonObj.put("ruleName", pcyRule.getRuleName());
                                    jsonObj.put("type", policy.getMajorType());
                                    jsonObj.put("prodName", saleOrderItem.getProdName());
                                    Double netPrice = saleOrderItem.getNetPrice();
                                    Double promotionPrice = saleOrderItem.getPromotionPrice();
                                    Double num = saleOrderItem.getQty();
                                    Double policyPrice = saleOrderItem.getPolicyPrice();


                                    if (policyPrice != null && promotionPrice != null && num != null) {
                                        Double lessPrice = promotionPrice - policyPrice;
                                        Double finalLess = lessPrice * num;
                                        jsonObj.put("num", finalLess);
                                    }
                                    jsonArrayLine.add(jsonObj);
                                }
                            }
                        }
                    }
                }
            }
        }
        jsonObjAll.put("wholeOrder", jsonArrayHead);
        jsonObjAll.put("orderItem", jsonArrayLine);
        return jsonObjAll.toJSONString();
    }

    /**
     * @param policy 政策信息
     * @param cndId  条件Id
     * @return 条件记录
     * @throws Exception 报错
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    private PcyRule getPcyRule(Policy policy, String cndId) throws Exception {
        List<PcyRule> pcyRuleList = policy.getRuleList();
        for (PcyRule rule : pcyRuleList) {
            List<PcyCnd> pcyCndList = rule.getConditionList();
            for (PcyCnd cnd : pcyCndList) {
                if (cndId.equals(cnd.getId())) {
                    return rule;
                }
            }
        }
        return null;
    }

    /**
     * @param policy 政策 ，必须有政策id ,主要组织id
     * @throws Exception 常规
     *                   HuangLJ
     *                   更新政策主要组织Id
     *
     * 备注：政策相关的文档，请到知识库搜索 【销售政策说明】
     */
    @Override
    public void updatePolicyMainOrg(Policy policy) throws Exception {
        Long id = policy.getId();
        Long orgId = policy.getOrgId();
        if (id == null) {
            throw new ServiceException("PUBLIC-007");
        }
        if (orgId == null) {
            throw new ServiceException("PUBLIC-004");
        }
        policyMapper.updatePolicyMainOrg(policy);
    }
}
